2016-06-21 80 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已修复。如果这是一个错误,任何解决方法的想法? –