让我们考虑一个非常简单的 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.MF
org/
org/apache/
...
META-INF/LICENSE.txt
images/
images/ant_logo_large.gif
虽然这首先看起来不像是一个问题,但它是一个巨大的问题,因为这个 JAR 将被拒绝,因为根据 JAR 规范META-INF/,它META-INF/MANIFEST.MF不是第一个条目。
我的用例非常相似,我想使用 ZIP 文件,并希望要求一些条目成为第一个快速验证输入的条目,而不必寻找到文件的末尾。
所有测试均使用 Java 8、10 和 11-ea。
那么问题来了,为什么 Zip 文件系统不保留流中出现的顺序呢?
MMMHUHU
相关分类