簡體   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