我可以在没有硬编码的Windows上运行Java的Linux路径吗?

时间:2018-06-12 10:12:36

标签: java linux windows windows-10 java-10

我正在使用Docker容器来托管Selenium中心和一些节点,我需要帮助这些测试找到一个静态HTML文件。我已将本地驱动器上的文件夹映射到Docker节点。

我的代码(Java 10,在Windows 10上运行)如下所示:

private URL getTestPageUrl() {
    var folder = Common.getString(Prop.testAssetFolder);
    var pathToTestPage = Paths.get(folder, "selectorTestPage.html");
    URL url = null;
    try { url = pathToTestPage.toUri().toURL(); }
    catch (MalformedURLException e) { /* Most pointlessly checked exception ever. */ }
    return url;
}

pathToTestPage\testAssets\selectorTestPage.html的形式出现,然后.toUri().toURL()会转换为file:/C:/testAssets/selectorTestPage.html,这当然不会在Linux上传播。

显然,我可以将一些文件夹和文件名以及一些硬编码/粘合在一起以获得Linux格式的这条路径,但是有更优雅的方式吗?

2 个答案:

答案 0 :(得分:1)

在阅读之前注意BitSet的Javadoc和相关API描述了许多方法的行为,因为它们依赖于实现。这有意义,因为不同的文件系统具有不同的规则。话虽如此,默认FileSystem的定义相当合理(因为它们模拟了主要的操作系统)。

静态方法FileSystem委托给平台的默认Paths.get(String, String...)。这与FileSystem获得的FileSystem相同。这意味着在Windows上它委托给FileSystems.getDefault(),在Linux上它委托给WindowsFileSystem(如果这是名字),依此类推。所述LinuxFileSystem的责任是实际创建FileSystem对象。这涉及添加正确的分隔符和验证每个名称之类的事情。分隔符由Path公开定义。

当您在Windows上呼叫FileSystem.getSeparator()时,返回的Paths.get("foo", "bar", "file.txt")可能会Path。在Linux上它将成为foo\bar\file.txt。我甚至发现,至少在Windows上传递一个名称实际上是错误分隔符的路径是非常宽容的。例如,在Windows上调用foo/bar/file.txt仍会返回Paths.get("foo/bar/file.txt")

您还可以拨打foo\bar\file.txtpath.toUri().toURL()州的Javadoc(强调我的):

  

此方法使用等于标识提供程序的URI方案的方案构造绝对 URI。方案特定部分的确切形式取决于提供者。

     

对于默认提供程序,URI是分层的,路径组件为绝对

     

...

     

抛出

     

...

     

SecurityException - 如果是默认提供程序,并且安装了安全管理器,则 toAbsolutePath 方法会引发安全性异常。

对亲戚toUri()的{​​{1}}电话会先找到绝对Path.toUri()。而且,基于Javadoc,我会说默认Path将通过调用Path获得绝对FileSystem。这意味着Path将根据您当前所在的平台解析为绝对路径。如您所见,Windows上的调用导致Path.toAbsolutePath()被添加为根。这不会发生在Linux机器上。此外,现在是Path定义路径中使用的分隔符。调用C:/也由URI定义。

在使用toURL()时,平台之间显然仍然存在问题。总会有你需要注意的问题和不兼容性。一个例子是Windows如何具有case- 不敏感的文件系统,而Linux是(我相信)case- 敏感

了解代码的唯一可靠方法就是在每个目标平台上运行测试。

答案 1 :(得分:0)

您应该可以使用NIO.2' FileSystemProvider,特别是sun.nio.fs.UnixFileSystemProvider

这允许你做类似

的事情
FileSystemProvider fsp = new UnixFileSystemProvider();
Path path = fsp.getPath(pathToTestPage.toUri());