在一个示例中:
var assets = "images/"
var sounds = assets+"sounds/"
将斜杠放在文件路径的后面是否更常规?
var assets = "/images"
var sounds = assets+"/sounds"
还有另一种方法是一种好的通用做法吗?
File.separator
尽管您很少需要使用,File
and Path
API都接受/
和`\`。
在一个示例中:
var assets = "images/"
var sounds = assets+"sounds/"
将斜杠放在文件路径的后面是否更常规?
var assets = "/images"
var sounds = assets+"/sounds"
还有另一种方法是一种好的通用做法吗?
File.separator
尽管您很少需要使用,File
and Path
API都接受/
和`\`。
Answers:
几乎每种主要的编程语言都有一个库来为您处理目录分隔符。您应该利用它们。这将简化您的代码并防止错误。
以我的经验,组合这样的字符串的通常原因是它们来自不同的来源。有时,它与配置文件不同。有时,它是与函数参数组合的常量。在任何情况下,当它们来自不同的来源时,您都必须考虑几种不同的可能情况,涉及要组合的末端的分隔符:
"images/"
和"/sounds"
"images"
和"/sounds"
或"images/"
和"sounds"
"images"
和"sounds"
每个部分来自不同来源的事实意味着,如果有人对此有所考虑,则每个来源可能会对遵循哪些约定有自己的看法!无论调用什么代码,都不必为此担心。您的代码应处理所有情况,因为有人会违反您的约定。这将浪费时间调查错误原因并进行修复。我曾在几次不愉快的场合中,一位同事对如何在配置文件中格式化路径进行了假设,这意味着我不得不去寻找代码并弄清楚他们的期望(或修正代码)。
大多数主要语言都为您提供了一种可以处理许多情况的方法:
os.path.join
对于PythonFile.join
对于RubyPath.join
用于Node.jsPaths.get
Java(7以上)Path.Combine
适用于.NET这些有一个警告。其中许多似乎都假定第二个参数中的前导目录分隔符引用了根路径,这意味着第一个参数应完全删除。我不知道为什么这被认为有用。对我来说,这只会引起问题。我从不想合并两个路径部分并以删除第一部分结束。在特殊情况下,请仔细阅读文档,并在必要时编写一个包装程序,而不是对其进行特殊处理,该包装程序可以满足您的要求。
如果您需要支持不同的操作系统,这还可以提供帮助。这些类几乎无所不在地说明了选择正确的分隔符的原因。库通常也可以通过标准化路径来适应OS约定。
如果您的编程语言没有易于使用的库,则应编写一种方法来处理所有这些情况,并在项目中自由使用。
属于“不要做假设”和“使用可以帮助您的工具”类别。
C:\Documents and Settings\Admin
与my folder:document.txt
* nix系统结合使用的库,这是/home/admin/my folder/document.txt
一个很可爱的技巧,但是在现实世界中,涉及的启发式方法引入了比其修复的错误更多的错误。
Paths.get()
只需将单个对象转换String
为Path
对象即可。要连接路径,您Path.resolve()
可以使用,可以使用另一个Path
或一个String
。Path
该类中还有其他方法可以进一步以各种方式联接路径。
Paths
。
[System.IO.Path]::Combine("abc", "\def")
具有上述行为的.NET方法的替代方法是cmdlet Join-Path "abc" "\def"
,它提供了"abc\def"
。
在Java中,答案将是“以上都不是”。最佳实践是使用java.io.File
类来组装路径名。例如
File assets = new File("images");
File sounds = new File(assets, "sounds");
该File
班还负责特定平台的路径分隔符。
还有一个单独的问题,即您的路径名是否应以斜杠开头。但这更多的是正确性,而不是最佳实践。以斜杠开头的路径名与不带斜杠的路径名有所不同!
核心(ECMA)Javascript库中没有对路径名处理的明确支持,但是(至少)Node.js通过Path模块提供了支持。
os.path.join
。PowerShell具有join-path
。我会在此答案中添加一些内容。我发现,如果您需要多个文件路径,那么如果您假设它们中的任何一个在特定位置都具有文件路径,则会使代码非常脆弱。使用这些类不仅有助于可移植性,还可以处理所有可能的边缘情况(要连接的两端都有斜线,一侧只有斜线,而根本没有斜线)。在配置文件中删除文件路径时,这种灵活性非常宝贵。
请注意,在.NET中,您应该使用Path.Combine方法。
var path = System.IO.Path.Combine("assets", "sounds");
原因是它“知道” 构造文件夹名称时要使用的正确字符。
这消除了修复前或修复后的“问题”。
os.path.join('src', '../../../your_secret_stuff')
是在Python有效; 换句话说,不要在用户输入时盲目使用这些方法。
文件夹和文件仅在一个方面有所不同:文件夹以斜杠结尾,而文件没有。此外,绝对路径以/
相对路径不开始。如果使用此方法,则始终将路径和文件连接在一起不会有问题。
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
将两个绝对路径连接在一起毫无意义,因为第二条路径应该相对于第一条路径。将两个相对路径连接在一起没有问题,但是如果程序不知道相对路径相对于何处,则可能导致不确定的行为。
var a = "/my/path" + "css/" + "test.css"; //Output: "/my/pathcss/test.css"
absolutepath
应该以斜杠结尾,因为这是一条路径。我以某种方式忽略了这一点。
我认为在实现路径方面没有任何魔术或“通用做法”,但是字符串串联当然不是可行的方法。您可以开发自己的用于处理案例的API,但是可能需要一些努力。特别是,您应该注意不同的平台。例如,在Windows中\
是分隔符,而在基于Unix的系统中/
是分隔符。
我不熟悉Javascript库,但是我确定应该有用于处理这些情况的库。例如,在Java中,您可以使用Path API来处理平台无关的路径操作。
/
作为路径文件名定界符。这确实需要命令行中的怪癖,但文件I / O API可以很好地与正斜杠一起使用。
我个人的喜好是这样的:
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
,但不是那么简单:)还可以选择检查双斜杠并清理它们。其他方法无法选择。
/
)开头的路径都是绝对路径,而不是相对路径。还是只针对第一个路径部分以外的路径?
/somewhere
是相对路径,因为它不包含主机,因此浏览器将根据当前页面的主机进行查找。在Web世界中,它http://here/somewhere
是一个绝对URI,并且/somewhereelse
是相对于它的。在文件系统世界中,它/somewhere
是绝对的,来自root /
,而“ somewhereelse”是相对于当前工作目录的。
http://here/somewhere
是具有绝对路径的URI,/somewhere
是以绝对路径的相对参考和somewhere/else
是具有相对路径的相对参考。显然,在那些圆圈中,“相对路径”用来指相对参考。
在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/' / ''
等等,以确定适当的行为。