Linux 上的 Java Paths.get() 奇怪行为

sem*_*emi 5 java linux windows path java-7

我目前正在编写一些代码,我经常在其中处理文件。我使用 Java 7 nio 类 Paths 和 Path 实现了所有文件路径处理(连接、规范化等)。在 Windows 上,一切都按预期工作,但是在 Linux 上,Paths 类的行为似乎被破坏了。

例如下面的代码:

    System.out.println(File.separator);
    System.out.println(FileSystems.getDefault());
    Path path = Paths.get("../dir1/", "\\dir2\\file1").toAbsolutePath().normalize();
    System.out.println(path);
    if(path.toFile().exists()) {
        System.out.println(path + " exists");
    }
Run Code Online (Sandbox Code Playgroud)

在 Windows 上打印以下输出:

\
sun.nio.fs.WindowsFileSystem
D:\projects\dir1\dir2\file1
true
Run Code Online (Sandbox Code Playgroud)

但是在 Java 1.7.0_79(64 位)和 Java 1.8.0_60(64 位)上的 Linux Ubuntu 14.04 上的相同代码使路径未规范化:

/
sun.nio.fs.LinuxFileSystem
/home/semi/dir1/\dir2\file1
Run Code Online (Sandbox Code Playgroud)

此外,即使文件在路径中/home/semi/dir1/dir2/file1存在,它也会被报告为不存在path.toFile().exists()

我查看了一下LinuxFileSystem.javaWindowsFileSystem.java,似乎在 Windows 上,路径被检查了/\字符(在WindowsPathParser.isSlash(char c)方法中)。Linux 实现不应该这样做吗?

这是sun.nio.fs.LinuxFileSystem实现中的错误还是我做错了什么?

您还知道确保正确解析和规范化 Linux 路径的任何替代方法(无需手动进行所有解析)。

Ala*_*ack 1

在 Windows 中,/不是文件名中的有效字符,因此任何代码都可以假定它是错误键入的路径分隔符。

在 Linux 中,文件名中几乎任何字节都是可接受的。在您的 中Paths.get(),您实际上正在加入一条名为(1 级深)的路径和一条名为(也是 1 级深)dir1的路径。\dir2\file1

  • 因此,简而言之,基本上一直使用“/”作为路径分隔符,除非处理一些非常深奥的东西。 (3认同)