为了账号安全,请及时绑定邮箱和手机立即绑定

Java ZipFileSystem 在遍历时不保留物理顺序

Java ZipFileSystem 在遍历时不保留物理顺序

隔江千里 2021-08-04 17:46:32
让我们考虑一个非常简单的 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 条目和其他您并不总是需要的内部细节。


查看完整回答
反对 回复 2021-08-04
  • 1 回答
  • 0 关注
  • 261 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信