2016-06-21 38 views
2

爲了保持對zip文件的引用而不必保持zip文件的打開狀態,我希望將URI保存到zip文件的條目中。如果路徑中包含空格,則Zip中的文件的URI不正確

因此,我使用zip文件系統打開zip文件並將條目的路徑導出爲URI。

Path zipfile = ... 
URI uriOfFileInZip; 
try(FileSystem fs = FileSystems.newFileSystem(zipfile, null)){ 
    Path fileInZip = fs.getPath("fileInZip.txt"); 
    uriOfFileInZip = fileInZip.toUri(); 
} 

現在我想再次讀取文件,所以我嘗試打開文件流。

​​

這隻要工作作爲ZIP文件不包含任何空格的路徑。只要它包含空格,我得到這樣

java.io.FileNotFoundException: D:\example\name%20of%20zipfile.zip (The system cannot find the file specified) 

的URI的錯誤在zip文件是

jar:file:///D:/example/name%2520of%2520zipfile.zip!/fileInZip.txt 

拉鍊的名稱是

D:\example\name of zipfile.zip 

我想知道%2520這似乎是URL編碼的問題,但不應該透明地處理這個問題嗎?或者它是一個錯誤?

任何想法來解決這個問題?

回答

2

看起來像一個錯誤。

好像com.sun.nio.zipfs.ZipPath.toUri()要麼搞砸了,要麼我沒看過相應的RFC ;-)。玩過其他一些文件名。似乎有一個zip文件路徑的雙重編碼,但不是zip中的文件條目。 除了不使用URI方法,你也可以從頭開始構建URI,但是你不再那麼靈活。或者你只是取消了不必要的編碼:

String uriParts[] = uriOfFileInZip.toString().split("!"); 
uriParts[0] = URLDecoder.decode(uriParts[0], "UTF-8"); 
uriOfFileInZip = URI.create(String.join("!", uriParts)); 

但說實話,我寧願儘量省略URI的zip文件,或者如果你真的要,先重命名文件;-)更妙的是:打開錯誤,如果它不符合相應的RFC中所述的行爲。

您可能還需要得到有關的bug,等: Java 7 zip file system provider doesn't seem to accept spaces in URI

EDIT(不添加URI方案)的以下問題的一些附加信息:

您也可以嘗試將其完全工作與你的Path實例(fileInZip)而不是URI,因爲路徑實例「知道」它的文件系統。 只要需要訪問zip中的文件,就可以根據Path實例的信息(fileInZip.getFileSystem())創建一個新的FileSystem。我沒有完全闡述,但至少文件存儲應該包含所有必要的信息來再次訪問zip文件。有了這些信息,你可以打電話給FileSystems.newFileSystem(Paths.get(fileStoreName), null)。 然後您也可以使用Files.newInputStream(fileInZip)來創建您的InputStream。這裏不需要使用URI。

+0

這是相關的,但似乎是另一個問題。我使用空格的路徑創建zipfs,而當我使用Java 8時,這篇文章中提到的bug已修復。如果這是一個錯誤,任何解決方法的想法? –

相關問題