質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Q&A

解決済

4回答

11033閲覧

zipファイルに入っているファイルの順序はzipに格納した順?それとも?

toroleaman

総合スコア95

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

0グッド

1クリップ

投稿2015/10/29 01:55

###知りたいこと
複数のファイルを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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

Javadocに無いように見えるので、実装依存ではあると思います。
基本的には、argiusさんの書いているとおり、自然な実装では書き込み順に読み込まれると思います。

実際にjdk8u60のソースを見ると、
zipへのエントリの書き込み時に、書き込み順に中央ディレクトリにも書き込んでおり、
zipからのエントリの読み込み時(ZipFilesのentriesでの読み込み)には
中央ディレクトリに有る順で読み込んでいるようなので、
実装上は書き込んだ順に読み込んでいるのだと思います。

以下、ソースを見た内容です。
あまり詳細には見ていないので、細かい条件は他にあるかも知れません。

書き込み順に中央ディレクトリにも書き込んでいる箇所

http://hg.openjdk.java.net/jdk8u/jdk8u60/jdk/file/935758609767/src/share/classes/java/util/zip/ZipOutputStream.java

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での読み込み)

http://hg.openjdk.java.net/jdk8u/jdk8u60/jdk/file/935758609767/src/share/classes/java/util/zip/ZipFile.java

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

eripong

総合スコア1546

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toroleaman

2015/10/30 16:06

格納した順に読み込んでいるということですね。ありがとうございます。
guest

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
argius

総合スコア9390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toroleaman

2015/10/29 16:44

動作を見る限り、格納した順番で取り出せているので、 そのように動作するのかもしれませんが、、、 腑に落ちないですね。
argius

2015/10/30 07:11 編集

すみません、時間が無くて詳しいことを書けませんでしたが、少しだけ補足しました。 Javaの実装についてはeripongさんが全部書いてくれたのでそちらをご覧ください。
guest

0

toroleaman様

その記述だとランダムですね。
出来上がるファイル名も毎回違うかとおもいます。

投稿2015/10/29 09:01

takato

総合スコア148

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toroleaman

2015/10/29 16:46

回答ありがとうございます。 zipから取り出すと入れた順にファイルが取り出せました。 ランダムなんでしょうか?
takato

2015/10/30 05:23

toroleaman様 取り出す順は変わらないですよ! zipで出来上がるファイル名が毎回違うということです。 誤解を与えてしまい申し訳ございません。
toroleaman

2015/10/30 16:04

なるほどです。ありがとうございます。
guest

0

JavaDocには特に明記がないので想像になりますが。File#listFilesと同様に不定だと思います。

投稿2015/10/29 08:36

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toroleaman

2015/10/29 16:49

回答ありがとうございます。 File#listFilesも確かに不定ですね。listFilesもソートされているように見えることがありますよね。けど、listFilesは不定だから、zipもそうなんだろうなと想像はできますね。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問