让我们考虑一个非常简单的 Java 片段:String pathUriStr = Paths.get(args[0]).toUri().toASCIIString();URI zipUri = URI.create("jar:" + pathUriStr);FileSystem zip = null;try { zip = FileSystems.newFileSystem(zipUri, Collections.emptyMap());} catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace();}Path zipRoot = zip.getPath("/");System.out.println("ZipFileSystem:");FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println(file); return super.visitFile(file, attrs); } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println(dir); return super.preVisitDirectory(dir, attrs); }};try { Files.walkFileTree(zipRoot, visitor);} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();}输出是:ZipFileSystem://images/images/ant_logo_large.gif/org/org/apache.../META-INF/META-INF/LICENSE.txt/META-INF/MANIFEST.MF对 `ZipInputStream 做同样的事情:System.out.println("ZipInputStream:");try (InputStream is = Files.newInputStream(Paths.get(args[0]), StandardOpenOption.READ); ZipInputStream zipIs = new ZipInputStream(is)) { ZipEntry entry = null; while((entry = zipIs.getNextEntry()) != null) { System.out.println(entry); zipIs.closeEntry(); }} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();}给我:ZipInputStream:META-INF/META-INF/MANIFEST.MForg/org/apache/...META-INF/LICENSE.txtimages/images/ant_logo_large.gif虽然这首先看起来不像是一个问题,但它是一个巨大的问题,因为这个 JAR 将被拒绝,因为根据 JAR 规范META-INF/,它META-INF/MANIFEST.MF不是第一个条目。我的用例非常相似,我想使用 ZIP 文件,并希望要求一些条目成为第一个快速验证输入的条目,而不必寻找到文件的末尾。所有测试均使用 Java 8、10 和 11-ea。那么问题来了,为什么 Zip 文件系统不保留流中出现的顺序呢?
1 回答
MMMHUHU
TA贡献1834条经验 获得超8个赞
ZipFileSystem
是底层 zip 文件的抽象,允许您以与FileSystem 的任何其他实现相同的方式处理它。从根开始,让它在您期望的常规树状结构中工作是非常有意义的/
。如果您想轻松地从/向 zip 复制文件,这非常棒,就像您在常规目录之间所做的那样。这样做的缺点是您对 zip 本身失去了一些控制。
ZipInputStream
是一个更低级别的抽象,您可以在其中控制结构和其他 zip 文件特定的内容。缺点是您可能需要编写更多代码。
示例:您想将文件从一个 zip 复制或移动到另一个:
有了ZipFileSystem
这相当于移动从一个目录复制到另一个文件中,代码适用于任何执行FileSystem
。使用 zip 流,您必须手动处理源 zip 文件,找到正确的条目,删除条目,然后将其添加到第二个 zip 文件中,并在此过程中重写文件。这是 1 行代码与几行、循环和其他样板。
SoZipFileSystem
为您提供了更高抽象的好处,但也有缺点,例如内存使用、对 zip 文件细节的控制较少等。ZipXXXStream
为您提供 zip 的低级视图,处理 zip 条目和其他您并不总是需要的内部细节。
添加回答
举报
0/150
提交
取消