我正在使用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格式的这条路径,但是有更优雅的方式吗?
答案 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.txt
。 path.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());