假设我们有这样的代码:
File file = new File("zip1.zip");
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
假设您有一个.zip文件,其中包含以下内容:
- zip1.zip
- hello.c
- world.java
- 文件夹1
- foo.c
- bar.java
- foobar.c
zis.getNextEntry()将如何遍历它?
它会返回hello.c、world.java、folder 1、foobar.c并完全忽略folder 1中的文件吗?
或者返回hello.c、world.java、folder 1、foo.c、bar.java,然后返回foobar.c?
它甚至会返回folder 1,因为它在技术上是一个文件夹,而不是一个文件?
谢谢!
5条答案
按热度按时间mbjcgjjk1#
嗯……让我们看看:
输出:
新建文件夹/
新建文件夹/folder 1/
新文件夹/folder 1/bar.java
新建文件夹/folder 1/foo. c
新建文件夹/foobar. c
新建文件夹/hello. c
新文件夹/world.java
3qpi33ja2#
是的。它也会打印文件夹名称,因为它也是zip中的一个条目。它也将打印在相同的顺序,因为它是显示在zip。您可以使用下面的测试来验证您的输出。
eimct9ow3#
摘录自:https://blogs.oracle.com/CoreJavaTechTips/entry/creating_zip_and_jar_files
java.util.zip 库为ZipOutputStream的添加条目提供了某种级别的控制。
首先,向ZipOutputStream添加条目的顺序是它们在.zip文件中物理位置的顺序。
您可以操作ZipFile的entries()方法返回的条目枚举,以按字母顺序或大小顺序生成列表,但条目仍按写入输出流的顺序存储。
所以我相信你必须使用entries()方法来查看它的迭代顺序。
gcxthw6b4#
zip文件内部目录是zip中所有文件和目录的“平面”列表。
getNextEntry
将遍历该列表,并按顺序标识zip文件中的每个文件和目录。zip文件格式有一个变体,它没有中心目录,在这种情况下(如果它被处理的话),我怀疑你会遍历zip中的所有实际文件,跳过目录(但不跳过目录中的文件)。
2exbekwf5#
我想更详细地解释为什么Vikram's answer是正确的,而accepted和highest scoring的答案可能会误导或不完整。
正如Vikram所说(正确)
将条目添加到
ZipOutputStream
的顺序是它们在.zip文件中物理位置的顺序。我发现这部分公认的答案可能会产生误导:
它也将打印在相同的顺序,因为它是显示在zip。
我想指出的一个问题是,文件夹中的文件不保证会连续返回。
不同的工具以不同的顺序显示zip文件内容。特别是,任何带有GUI的工具都会将文件夹中的所有文件显示在一起,而zip中的实际文件可能会分散在各处。
让我们看看下面的两个场景。
场景一:按树顺序排列的文件
从这样的文件树开始
现在让我们使用Linux
zip
命令从该目录创建一个zip。请注意这些文件的添加顺序。这与使用
ZipOutputStream
时迭代的顺序相同。用下面的脚本测试一下(借用Zoop的答案)场景二:文件散落
如果我们以不同的顺序添加文件,那么它们将以不同的顺序迭代。让我们尝试使用zip命令创建一个新文件,并将文件逐个添加到文件夹中:
现在,如果我们遍历这些文件,您将看到
folder1/bar.java
是最后一个条目,因为它是最后添加的。它不会与其他文件夹内容一起返回。目录条目不会重复或紧接在它之前。zip规范非常复杂,所以在使用ZipInputStream时要非常小心。