【问题标题】:Java Paths.get() strange behavior on LinuxJava Paths.get() 在 Linux 上的奇怪行为
【发布时间】:2015-12-03 20:12:40
【问题描述】:

我目前正在编写一些代码,我在其中经常处理文件。我使用 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");
    }

在 Windows 上打印以下输出:

\
sun.nio.fs.WindowsFileSystem
D:\projects\dir1\dir2\file1
true

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

/
sun.nio.fs.LinuxFileSystem
/home/semi/dir1/\dir2\file1

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

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

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

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

【问题讨论】:

  • 反之亦然:WindowsFileSystem 默默地将/ 视为分隔符,尽管没有指定这种行为,这可以被认为是一个错误。或便利功能,无论您喜欢哪种方式。不幸的是,这种行为导致开发人员期望从实现中获得魔力……
  • 如果你在路径元素Path path = Paths.get("..", "dir1", "dir2", "file1").toAbsolutePath().normalize();上构造Path,你可以避免这样的问题,你不需要自己处理File.separator

标签: java linux windows path java-7


【解决方案1】:

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

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

【讨论】:

  • 所以,简而言之,使用/ 作为路径分隔符,基本上一直使用,除非处理一些非常深奥的事情。
  • 如果您必须使用字符串,使用/ 是个好主意,但我会使用本机路径连接工具(如Paths.get())或在您的代码中手动使用File.separator,就像您一样已经做了。
  • 我没有想到 '\' 可能是一个可接受的 Linux 文件名字符。现在说得通了,我将继续使用 Paths.get 并确保我的路径中没有使用“\”。谢谢你:)
  • 好消息:反斜杠是许多可避免问题的根源。
【解决方案2】:

Windows 上的 Java 是针对 Microsoft C++ 标准库编译的,这些标准库允许反斜杠或正斜杠作为有效的路径分隔符。所以反斜杠只有在 Windows 上运行时才是有效的路径分隔符,而正斜杠在任何地方都有效。

唯一需要反斜杠的时候,即使在 Windows 上,也是在创建将传递给 CMD.EXE、PowerShell 和可能的其他终端/shell 的命令行时。还有一些开源库需要在文件路径中使用反斜杠(在 Windows 上运行时),但 java 本身允许在文件路径中使用正斜杠或反斜杠。

恕我直言,在解析输入时使用 File.separator 通常会导致可避免的错误,而在生成供软件或人眼使用的输出时它具有有效的作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多