是否有组合文件路径字符串的常规方法?


34

在一个示例中:

var assets = "images/"

var sounds = assets+"sounds/"

将斜杠放在文件路径的后面是否更常规?

var assets = "/images"

var sounds = assets+"/sounds"

还有另一种方法是一种好的通用做法吗?


Java具有听起来很相关的静态字符串File.separator和File.pathSeparator。这样,您在所有平台上都是安全的
Evorlor'1

1
@Evorlor File.separator尽管您很少需要使用,Fileand PathAPI都接受/和`\`。
kapex 2015年

2
您能指出您使用哪种语言吗?可能值得添加相应的标签。
Christopher Creutzig

@ChristopherCreutzig我正在使用Java-尽管我在问是否有任何常用的约定将文件目录组合在字符串中。显然,有一些普遍接受的规则,并且涉及一些常识,但是不同的语言会有一些差异。
虹彩

1
就其价值而言,在Unix世界中(以及在url中),路径中间的多个正斜杠与单个斜杠相同,因此,如果您犯了更多的斜杠,也不会发生任何不好的情况。它是Single Unix规范的一部分;看到这个答案-unix.stackexchange.com/a/1919/21161
yoniLavi 2015年

Answers:


37

几乎每种主要的编程语言都有一个库来为您处理目录分隔符。您应该利用它们。这将简化您的代码并防止错误

以我的经验,组合这样的字符串的通常原因是它们来自不同的来源。有时,它与配置文件不同。有时,它是与函数参数组合的常量。在任何情况下,当它们来自不同的来源时,您都必须考虑几种不同的可能情况,涉及要组合的末端的分隔符:

  • 两端可以有一个分隔符:"images/""/sounds"
  • 只有一个有分隔符:"images""/sounds""images/""sounds"
  • 都没有分隔符:"images""sounds"

每个部分来自不同来源的事实意味着,如果有人对此有所考虑,则每个来源可能会对遵循哪些约定有自己的看法!无论调用什么代码,都不必为此担心。您的代码应处理所有情况,因为有人会违反您的约定。这将浪费时间调查错误原因并进行修复。我曾在几次不愉快的场合中,一位同事对如何在配置文件中格式化路径进行了假设,这意味着我不得不去寻找代码并弄清楚他们的期望(或修正代码)。

大多数主要语言都为您提供了一种可以处理许多情况的方法:

这些有一个警告。其中许多似乎都假定第二个参数中的前导目录分隔符引用了根路径,这意味着第一个参数应完全删除。我不知道为什么这被认为有用。对我来说,这只会引起问题。我从不想合并两个路径部分并以删除第一部分结束。在特殊情况下,请仔细阅读文档,并在必要时编写一个包装程序,而不是对其进行特殊处理,该包装程序可以满足您的要求。

如果您需要支持不同的操作系统,这还可以提供帮助。这些类几乎无所不在地说明了选择正确的分隔符的原因。库通常也可以通过标准化路径来适应OS约定。

如果您的编程语言没有易于使用的库,则应编写一种方法来处理所有这些情况,并在项目中自由使用。

属于“不要做假设”和“使用可以帮助您的工具”类别。


2
.NET的Path.Combine没有损坏。只是不喂它的分隔符。确保您已阅读文档,如果第二个参数是根路径,则它具有定义的结果。您可能不喜欢它,但这并不意味着它坏了。
Erno 2015年

4
确保阅读了文档,以确保它不会太聪明。我曾经使用过一个可以成功地C:\Documents and Settings\Adminmy folder:document.txt* nix系统结合使用的库,这是/home/admin/my folder/document.txt一个很可爱的技巧,但是在现实世界中,涉及的启发式方法引入了比其修复的错误更多的错误。
2015年

1
另外,对于Java,Paths.get()只需将单个对象转换StringPath对象即可。要连接路径,您Path.resolve()可以使用,可以使用另一个Path或一个StringPath该类中还有其他方法可以进一步以各种方式联接路径。
凯特2015年

1
我的糟糕,看来我没有很好地阅读过文档Paths
凯特2015年

1
在PowerShell上,[System.IO.Path]::Combine("abc", "\def")具有上述行为的.NET方法的替代方法是cmdlet Join-Path "abc" "\def",它提供了"abc\def"
杰普·斯蒂格·尼尔森

38

在Java中,答案将是“以上都不是”。最佳实践是使用java.io.File类来组装路径名。例如

File assets = new File("images");
File sounds = new File(assets, "sounds");

File班还负责特定平台的路径分隔符。

还有一个单独的问题,即您的路径名是否应以斜杠开头。但这更多的是正确性,而不是最佳实践。以斜杠开头的路径名与不带斜杠的路径名有所不同


核心(ECMA)Javascript库中没有对路径名处理的明确支持,但是(至少)Node.js通过Path模块提供了支持。


4
.Net Framework语言和提供文件系统类的任何其他语言也是如此。
詹姆斯·斯内尔

3
谢谢!这似乎是最有用的答案,即使特定于语言,一般也应该为其他语言(如.NET和C ++)提供库。
虹彩

3
实际上,任何不使用库的代码都应在代码审查中被拒绝。在极少数情况下不存在任何库的情况下,答案是自己写一个而不是粘贴原始字符串。


Python有os.path.join。PowerShell具有join-path。我会在此答案中添加一些内容。我发现,如果您需要多个文件路径,那么如果您假设它们中的任何一个在特定位置都具有文件路径,则会使代码非常脆弱。使用这些类不仅有助于可移植性,还可以处理所有可能的边缘情况(要连接的两端都有斜线,一侧只有斜线,而根本没有斜线)。在配置文件中删除文件路径时,这种灵活性非常宝贵
jpmc26 2015年

21

请注意,在.NET中,您应该使用Path.Combine方法。

var path = System.IO.Path.Combine("assets", "sounds");

原因是它“知道” 构造文件夹名称时要使用的正确字符

这消除了修复前或修复后的“问题”。


4
os.path.join对于python基本上也做同样的事情
StarWeaver 2015年

请注意,path.combine不会使您摆脱担心分隔符的
麻烦

1
@jmoreno-在我的示例中没有分隔符。您链接到的问题具有硬编码的分隔符,如果根本上是错误的,因为第二条路径是绝对路径。
埃尔诺2015年

不过要小心。我不能确定有关.NET,但是os.path.join('src', '../../../your_secret_stuff') 在Python有效; 换句话说,不要在用户输入时盲目使用这些方法。
sapi 2015年

@sapi-当然,应该始终清除用户输入的内容,但这是程序员的责任,而不是API的责任。
埃尔诺2015年

5

在构建路径时,我经常使用一个函数来添加斜杠(如果尚不存在的话)。然后可以按照以下方式构建路径:

filename := fs( 'assets') + fs( 'images') + fs( 'icons') + 'some.png';

如果需要,fs()会在其后添加一个斜杠。


5

文件夹和文件仅在一个方面有所不同:文件夹以斜杠结尾,而文件没有。此外,绝对路径以/相对路径不开始。如果使用此方法,则始终将路径和文件连接在一起不会有问题。

var absolutepath = "/my/path/";
var relativepath = "css/";
var filename = "test.css";
var relativepathtofilename = "js/test.js";

var a = absolutepath + relativepath + filename; //Output: /my/path/css/test.css
var b = absolutepath + relativepathtofilename;  //Output: /my/path/js/test.js

将两个绝对路径连接在一起毫无意义,因为第二条路径应该相对于第一条路径。将两个相对路径连接在一起没有问题,但是如果程序不知道相对路径相对于何处,则可能导致不确定的行为。


这可能最好地回答了我最初的问题,我认为我对文件路径的理解更好,尽管像Stephen C和Erno所说的那样,语言库是最好的选择。这可以更好地解释约定。谢谢!
虹彩

文件系统路径或URL?
MrWhite 2015年

1
出于所有目的和目的,您也可以将此方法应用于uri。绝对uri将从协议开始,但除此之外,我认为也是一样。
Sumurai15年

不确定您的输出如何工作。当我这样做时,我得到:var a = "/my/path" + "css/" + "test.css"; //Output: "/my/pathcss/test.css"
Damon

1
@Damon我进行了编辑。absolutepath应该以斜杠结尾,因为这是一条路径。我以某种方式忽略了这一点。
Sumurai16年

4

我认为在实现路径方面没有任何魔术或“通用做法”,但是字符串串联当然不是可行的方法。您可以开发自己的用于处理案例的API,但是可能需要一些努力。特别是,您应该注意不同的平台。例如,在Windows中\是分隔符,而在基于Unix的系统中/是分隔符。

我不熟悉Javascript库,但是我确定应该有用于处理这些情况的库。例如,在Java中,您可以使用Path API来处理平台无关的路径操作。


3
Windows实际上确实支持/作为路径文件名定界符。这确实需要命令行中的怪癖,但文件I / O API可以很好地与正斜杠一起使用。
Ruslan'1

en.wikipedia.org/wiki/… “ Windows系统API接受斜杠,因此上述所有Unix示例均应适用。但是Windows上的许多应用程序都会将斜杠解释为其他用途,或者将其视为无效字符,因此要求您输入反斜杠-特别是cmd.exe shell(通常在终端窗口中运行,通常称为“终端”)。
Mooing Duck 2015年

0

我个人的喜好是这样的:

var assets = "/images"

var sounds = assets+"/sounds"

我一直使用绝对路径(/images/...),对我来说,它不太容易出错。它也更易于使用,var sounds = assets+"/sounds"因为即使assets有斜杠并且您最终得到了/images//sounds,它仍然会解决/images/sounds。一个免责声明是它取决于您的请求处理程序。Apache似乎可以很好地处理它(至少某些版本/配置,请参阅http://www.amazon.com//gp//site-directory//ref=nav_sad)。用另一种方法,您最终会得到/imagessounds,但不是那么简单:)还可以选择检查双斜杠并清理它们。其他方法无法选择。


11
在我所知道的所有情况下,以斜杠(/)开头的路径都是绝对路径,而不是相对路径。还是只针对第一个路径部分以外的路径?
Bart van Ingen Schenau 2015年

@BartvanIngenSchenau我完全同意您的看法,多年来一直给他们打电话,但每次阅读前端开发人员写的文章时,他们都将它们称为相对路径。我不想做假设,所以我想我选择了两个弊端中的较小者……?现在,我知道我身边有一些人,我将更新我的答案:)
rpaskett 2015年

2
对于Web开发人员来说,/somewhere是相对路径,因为它不包含主机,因此浏览器将根据当前页面的主机进行查找。在Web世界中,它http://here/somewhere是一个绝对URI,并且/somewhereelse是相对于它的。在文件系统世界中,它/somewhere是绝对的,来自root /,而“ somewhereelse”是相对于当前工作目录的。
罗布

3
@RobY,rpaskett:通过去RFC3986(该RFC定义的URI),http://here/somewhere是具有绝对路径的URI,/somewhere是以绝对路径的相对参考和somewhere/else是具有相对路径的相对参考。显然,在那些圆圈中,“相对路径”用来指相对参考。
Bart van Ingen Schenau 2015年

1
@BartvanIngenSchenau:在Windows中,以斜杠开头的路径是相对路径,并且相对于CWD。 en.wikipedia.org/wiki/...
鸣叫鸭

0

在Smalltalk中,很容易在String中定义/方法,使其工作如下:

'assets' / 'sounds' => 'assets/sounds'.
'assets/' / 'sounds' => 'assets/sounds'.
'assets' / '/sounds' => 'assets/sounds'.
'assets/' / '/sounds' => 'assets/sounds'.

这是该方法的简单实现(您可以使其变得更好):

/ aString
    | slash first second |
    slash := Directory separator.
    first := self.
    (first endsWith: slash) ifTrue: [first := first allButLast].
    second := aString.
    (second beginsWith: slash) ifTrue: [second := second allButFirst].
    ^first , slash , second

注意:您可能还需要多加留意边境的情况下,例如'' / '''x/' / ''等等,以确定适当的行为。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.