繁体   English   中英

我可以在没有硬编码的情况下在 Windows 上运行 Java 中构建 Linux 路径吗?

[英]Can I build a Linux path in Java running on Windows without hard-coding?

我正在使用 Docker 容器托管 Selenium 集线器和一些节点,我需要帮助这些测试找到 static1 Z4C4AD5FCAED038 Z4C4AD5FCAED037 文件。 我已将本地驱动器上的文件夹映射到 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 comes out as \testAssets\selectorTestPage.html , which .toUri().toURL() then converts to file:/C:/testAssets/selectorTestPage.html , which of course doesn't fly on Linux.

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

阅读前请注意FileSystem的Javadoc和相关的API将许多方法的行为描述为与实现相关的。 这是有道理的,因为不同的文件系统具有不同的规则。 话虽如此,默认FileSystem的定义相当合理(因为它们对主要操作系统进行了建模)。

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

在Windows上调用Paths.get("foo", "bar", "file.txt")时,返回的Pathfoo\\bar\\file.txt 在Linux上,它将变成foo/bar/file.txt 我什至发现,至少在Windows上,传入一个实际上是带有错误分隔符的路径的名称是相当宽容的。 例如,在Windows上调用Paths.get("foo/bar/file.txt")仍会返回foo\\bar\\file.txt

您还可以调用path.toUri().toURL() toUri()的Javadoc状态(强调我的意思):

此方法使用等于标识提供者的URI方案的方案构造绝对 URI。 方案特定部分的确切形式高度依赖于提供者。

对于默认提供程序,URI是具有绝对路径的分层结构。

...

投掷

...

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

在相对Path上对Path.toUri()调用将首先找到绝对Path 而且,基于Javadoc,我想说默认FileSystem将通过调用Path.toAbsolutePath()获得绝对Path 这意味着Path被解析为基础的平台,你目前上的绝对路径。 如您所见,在Windows上的调用导致C:/被添加为根。 例如,这不会在Linux机器上发生。 而且,现在是URI定义了路径中使用的分隔符。 并且对URI toURL()的调用也由URI定义。


显然,使用java.nio时,平台之间仍然存在问题。 总是会有一些陷阱和不兼容之处,您需要提防。 一个例子是Windows如何具有不区分大小写的文件系统,而Linux的(我相信)是区分大小写的

正确跨平台了解代码的唯一确定方法是在每个目标平台上运行测试。

您应该能够使用NIO.2的FileSystemProvider ,特别是sun.nio.fs.UnixFileSystemProvider

那可以让你做类似的事情

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

如果 String 结果可以接受,请考虑结合 Paths.get(...) 和 Apache Commons IO 的强大功能:

Path path = Paths.get(folder, "selectorTestPage.html"); 
return FilenameUtils.separatorsToUnix(path.toString());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM