File.separator与路径中的斜杠之间的区别

Joe*_*e23 189 java

在Java Path-String中使用File.separator和普通/有什么区别?

与双反斜杠\\平台相比,独立性似乎不是原因,因为两个版本都可以在Windows和Unix下运行.

public class SlashTest {
    @Test
    public void slash() throws Exception {
        File file = new File("src/trials/SlashTest.java");
        assertThat(file.exists(), is(true));
    }

    @Test
    public void separator() throws Exception {
        File file = new File("src" + File.separator + "trials" + File.separator + "SlashTest.java");
        assertThat(file.exists(), is(true));
    }
}
Run Code Online (Sandbox Code Playgroud)

要重新解释这个问题,如果/适用于Unix和Windows,为什么要使用File.separator

Poi*_*nty 300

你使用的File.separator是因为有一天你的程序可能会运行在一个遥远的土地上开发的平台上,一个奇怪的东西和陌生人的土地,在那里马匹哭泣,奶牛操作所有的电梯.在这片土地上,人们传统上使用":"字符作为文件分隔符,因此JVM尽职尽责地遵循他们的意愿.

  • 在这样的国家,你可以使用新的org.apache.chicken.elevators.OperatorUtility类,它为了你的方便而嵌入了所有这些疯狂. (7认同)
  • 是的,Pointy真的把我们带到了elbonia(希望他没有尖尖的发型;-)(极客双关语) (4认同)
  • *"......奶牛操作所有的电梯."*当我阅读时,我也没有喝一口咖啡.辉煌. (4认同)

T.J*_*der 230

使用用于处理文件的Java库,您可以/在所有平台上安全地使用(斜杠,而不是反斜杠).库代码处理内部将事物转换为特定于平台的路径.

File.separator但是,您可能希望在UI中使用,因为最好向人们展示在他们的操作系统中有意义的东西,而不是对Java有意义的东西.

更新:在五分钟的搜索中,我无法找到记录下"你总是可以使用斜线"的行为.现在,我确信我已经看到它记录在案,但由于没有找到官方参考(因为我的记忆并不完美),我坚持使用,File.separator因为你知道它会起作用.

  • @Powerlord:如果Windows也这样做,那很好 - 但是库(不是JVM)也可以.具体来说,`File`在整个地方使用`FileSystem.normalize`来"规范化"通过公共API接收的路径,几乎任何处理文件路径字符串的东西(例如,`FileWriter(String)`)都使用`File`在掩护下. (12认同)
  • 从Java7开始,就不再需要使用File.separator了.使用java.nio.file.Paths(Paths.get(first,more ...))对于dir和dir到文件名连接更加简单和清晰. (9认同)
  • @TJ Crowder:"在五分钟的搜索中,我无法找到'你总是可以使用斜线'的行为." 它不是JVM的一个功能,它是Windows NT API的一个特性. (7认同)
  • @jpabluz'性能问题'!你是认真的吗?考虑到使用文件名被放在磁盘上,翻译的运行时影响是完全无关紧要的.任何JVM都应该支持它,因为它是`File`规范的一部分. (6认同)
  • 这也可能是性能问题,因为您希望在运行时将分隔符转换为其他内容.此外,不要指望在所有不受支持的JVM中都会发生这种情况. (2认同)

Yis*_*hai 27

虽然使用文件分割符来引用文件名是矫枉过正(对于那些谁想象遥远的土地,我想象他们的JVM实现将替换/:,就像窗户JVM用替换它\).

但是,有时您获取文件引用,而不是创建它,并且您需要解析它,并且为了能够这样做,您需要知道平台上的分隔符.File.separator可以帮助您实现这一目标.


Ali*_*adi 9

好吧,让我们检查一些代码.
File.java第428至435行File.<init>:

String p = uri.getPath();
if (p.equals(""))
    throw new IllegalArgumentException("URI path component is empty");

// Okay, now initialize
p = fs.fromURIPath(p);
if (File.separatorChar != '/')
p = p.replace('/', File.separatorChar);
Run Code Online (Sandbox Code Playgroud)

让我们阅读fs/*(FileSystem)*/.fromURIPath()文档:

java.io.FileSystem
public abstract String fromURIPath(String path)
必要时对给定的URI路径字符串进行后处理.这在win32上使用,例如,将"/ c:/ foo"转换为"c:/ foo".路径字符串仍然有斜杠分隔符; File类中的代码将在此方法返回后转换它们.

这意味着FileSystem.fromURIPath()仅在Windows中对URI路径进行后期处理,因为在下一行中:

p = p.replace('/', File.separatorChar);
Run Code Online (Sandbox Code Playgroud)

它用系统相关的每个'/'替换seperatorChar,你总是可以确保'/'在每个操作系统中都是安全的.


jpa*_*luz 8

嗯,有比OS和Windows(便携式设备等)更多的操作系统,Java以其可移植性而闻名.最佳实践是使用它,因此JVM可以确定哪个最适合该操作系统.


Wil*_*ley 7

虽然它在路上没有太大的区别,但它确实在回来的路上.

当然你可以在新文件(字符串路径)中使用'/'或'\',但File.getPath()只会给你一个.


小智 6

聚会迟到了。我在使用 JDK 1.8 和 Eclipse MARS 1 的 Windows 10 上。
我发现

getClass().getClassLoader().getResourceAsStream("path/to/resource");

作品和

getClass().getClassLoader().getResourceAsStream("path"+File.separator+"to"+File.separator+"resource");

不起作用并且

getClass().getClassLoader().getResourceAsStream("path\to\resource");

不起作用。最后两个是等价的。所以...我有充分的理由不使用 File.separator。

  • 这是问题的不同场景。ClassLoader 的 getResourceAsStream 方法不采用 File 路径,而是采用 _resource name_,该名称可能位于文件系统上,也可能不在文件系统上,并且已[记录](https://docs.oracle.com/javase/8/docs/api/java/ lang/Class.html#getResourceAsStream(java.lang.String)) 作为只接受 '/' 作为资源路径分隔符。 (11认同)
  • 在这一行`getClass().getClassLoader().getResourceAsStream("path\to\resource");`中,有一个列表(`\t`)和一个回车(`\r`)。 (6认同)
  • @Stephan 哦,我明白了......你在谈论第三行。你是对的。在该行(硬编码字符串)中,您需要对转义字符进行转义。我的眼睛停在第二行,一开始我什至没有注意到第三行。 (2认同)