###知りたいこと
複数のファイルをzipファイルに圧縮した場合、
javaのZipFileクラスのentries関数を使うことで取得される
ファイルの順序はどのような順序で取得されるのでしょうか?
例えば、
AAA.txt
CCC.txt
BBB.txt
という順番でzipに格納した場合と
CCC.txt
BBB.txt
AAA.txt
という順番でzipに格納した場合とで、取り出される場合の順序が異なるのでしょうか。
参考までにzipを解凍する場合の処理を記載します。
java
1public void zipFileNameCheck(File file) throws Exception { 2 ZipFile zf = new ZipFile(file); 3 for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements();) { 4 ZipEntry entry = e.nextElement(); 5 System.out.println(entry.getName()); 6 } 7 zf.close(); 8 }
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
Javadocに無いように見えるので、実装依存ではあると思います。
基本的には、argiusさんの書いているとおり、自然な実装では書き込み順に読み込まれると思います。
実際にjdk8u60のソースを見ると、
zipへのエントリの書き込み時に、書き込み順に中央ディレクトリにも書き込んでおり、
zipからのエントリの読み込み時(ZipFilesのentriesでの読み込み)には
中央ディレクトリに有る順で読み込んでいるようなので、
実装上は書き込んだ順に読み込んでいるのだと思います。
以下、ソースを見た内容です。
あまり詳細には見ていないので、細かい条件は他にあるかも知れません。
書き込み順に中央ディレクトリにも書き込んでいる箇所
lang
1 /** 2 * Begins writing a new ZIP file entry and positions the stream to the 3 * start of the entry data. Closes the current entry if still active. 4 * The default compression method will be used if no compression method 5 * was specified for the entry, and the current time will be used if 6 * the entry has no set modification time. 7 * @param e the ZIP entry to be written 8 * @exception ZipException if a ZIP format error has occurred 9 * @exception IOException if an I/O error has occurred 10 */ 11 public void putNextEntry(ZipEntry e) throws IOException { 12-(略)- 13 current = new XEntry(e, written); 14 xentries.add(current); 15 writeLOC(current); 16 } 17
putNextEntryの最後でxentriesに追加していて、
finishの中で以下の様にxentriesに格納された順に中央ディレクトリに書き込んでいます(writeCEN)。
lang
1 /** 2 * Finishes writing the contents of the ZIP output stream without closing 3 * the underlying stream. Use this method when applying multiple filters 4 * in succession to the same output stream. 5 * @exception ZipException if a ZIP file error has occurred 6 * @exception IOException if an I/O exception has occurred 7 */ 8 public void finish() throws IOException { 9-(略)- 10 for (XEntry xentry : xentries) 11 writeCEN(xentry); 12 writeEND(off, written - off); 13 finished = true; 14 }
zipからのエントリの読み込み時(ZipFilesのentriesでの読み込み)
lang
1 /** 2 * Returns an enumeration of the ZIP file entries. 3 * @return an enumeration of the ZIP file entries 4 * @throws IllegalStateException if the zip file has been closed 5 */ 6 public Enumeration<? extends ZipEntry> entries() { 7 return new ZipEntryIterator(); 8 }
同じファイルのZipEntryIteratorを見ると、
lang
1ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> { 2 private int i = 0; 3-(略)- 4 public ZipEntry next() { 5 synchronized (ZipFile.this) { 6 ensureOpen(); 7 if (i >= total) { 8 throw new NoSuchElementException(); 9 } 10 long jzentry = getNextEntry(jzfile, i++);
getNextEntryはnativeメソッドなので、該当するソースを見ると、
http://hg.openjdk.java.net/jdk8u/jdk8u60/jdk/file/935758609767/src/share/native/java/util/zip/zip_util.c
lang
1/* 2 * Returns the n'th (starting at zero) zip file entry, or NULL if the 3 * specified index was out of range. 4 */ 5jzentry * JNICALL 6ZIP_GetNextEntry(jzfile *zip, jint n) 7{ 8 jzentry *result; 9 if (n < 0 || n >= zip->total) { 10 return 0; 11 } 12 ZIP_Lock(zip); 13 result = newEntry(zip, &zip->entries[n], ACCESS_SEQUENTIAL); 14 ZIP_Unlock(zip); 15 return result; 16} 17
zip->entriesをJavaのオブジェクトにしているようなので、
zip->entriesの初期化箇所を探すと、
lang
1/* 2 * Reads zip file central directory. Returns the file position of first 3 * CEN header, otherwise returns -1 if an error occurred. If zip->msg != NULL 4 * then the error was a zip format error and zip->msg has the error text. 5 * Always pass in -1 for knownTotal; it's used for a recursive call. 6 */ 7static jlong 8readCEN(jzfile *zip, jint knownTotal) 9{
で実施しているようですが、ここでは中央ディレクトリの格納順に読み出している様なので、
「zipからのエントリの読み込み時(ZipFilesのentriesでの読み込み)には
中央ディレクトリに有る順で読み込んでいる」
と言えそうです。
投稿2015/10/30 01:48
総合スコア1546
0
異なると思います。
JavaのAPI(java.util.zip
パッケージのクラス群)の正式な仕様・実装としてどうなのかは分かりませんが、
ZIPファイルの構造からして、おそらく格納した順番で取り出していると思うので。
参考リンク:
TNKソフトウェア - 私的ZIPファイル研究所
http://www.tnksoft.com/reading/zipfile/nonarc.php
(追記)
ちょっとだけ補足。
ZIPにはファイルシステムとは関係なくディレクトリーもファイルも(ディレクトリーエントリーが無いZIPも存在する)一緒くたに格納されます。
LOCヘッダー(PK0304)とCENヘッダー(PK0102)というものがあり、LOCヘッダーはエントリーごとに、CENヘッダーはZIPファイルの終了位置付近に置かれています。
ZIP展開時は、ファイルの情報はこのヘッダーを読み取って順次処理するはずなので、格納した順序で取り出すのが効率が良いし自然なわけです。
Javaの実装がどうなっているかはeripongさんが調べてくれたとおりです。
投稿2015/10/29 09:04
編集2015/10/30 02:57総合スコア9390
0
toroleaman様
その記述だとランダムですね。
出来上がるファイル名も毎回違うかとおもいます。
投稿2015/10/29 09:01
総合スコア148
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/10/29 16:46
2015/10/30 05:23
2015/10/30 16:04
0
JavaDocには特に明記がないので想像になりますが。File#listFilesと同様に不定だと思います。
投稿2015/10/29 08:36
総合スコア18155
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/10/29 16:49
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/10/30 16:06