質問: new byte[(int) file.length()]; ois.read(data); ois.close(); return data; } ``` 出力自体は成功してるように思います。 出力されたファイル内のtestが格納されており、 ファイルサイズがもとの一時ファイルと一致しているので... CRCがメタデータなのか、ファイルに含まれるのか、 よくわからないのでそこが原因かもしれませんが... 読み込み ---- 1指定されたファイル(ここでは上記したファイルを読み込む)を`JarInputStream`で読み込む 2`.getNextJarEntry()`を使ってJarEntryを取得 (ファイルは正しいものとして進めさせてください。実際圧縮しなければ読み込めました。) 3`FileOutputStream`で一時出力 4一時ファイルを`ObjectInputStream`で読み込む←ここで例外が飛ぶ 5オブジェクトを`.readObject()`で取得 例外の内容としては、 `java.io.StreamCorruptedException: invalid stream header: 00000000` もし圧縮すると、 `java.io.StreamCorruptedException: invalid stream header: 504B0304` という例外が同じところで飛んできます。 あとなんかハイライトされなんですけど、私が悪いんでしょうか(^_^;) --- バイト列を用いることで解決しました。 失礼しました。
回答: ``` byte[] objectData = ObjectInput(tempFile);//読み込む ``` この部分の`ObjectInput`メソッドの戻り値`objectData`を、例えば次のようなメソッドで出力してみるとわかりますが、想定されたように読み込まれていません。 (おそらく全て`0`で出力されると思います。) ``` private static void print(byte[] objectData) { for(byte c : objectData) { System.out.format("%d ", c); } } ``` つまり`ObjectInput`メソッドの実装に問題があります(ので、「圧縮しなければ問題ない」というのは何か勘違いをされているかと)。 ここでやりたいのは、ファイルをバイト列として読み込みたいだけなので、`ObjectInputStream`ではなく`FileInputStream`が適切だと思います。 したがって、`ObjectInput`メソッドは次のように実装することになります。 ``` public static byte[] ObjectInput(File file) throws IOException { FileInputStream fis = new FileInputStream(file); byte[] data = new byte[(int) file.length()]; fis.read(data); fis.close(); return data; } ``` 「バイト列を用いることで解決しました」というのがよく理解できなかったのですが、こちらの書き込みから想像するに、一時ファイルの作成をやめた(`ObjectInput`を使用しなくなった)ということですかね。 確かにこの処理自体不要です。 そんなわけで経緯をよく理解できていないのですが、オブジェクトをjarファイルに出力したいのであれば、あまり深く考えずに、そういうストリームを構築すれば良いのでは無いかと思います。 オブジェクトを書き出したいので`ObjectOutputStream`を使う、それをjar圧縮して最終的にファイルに、となるとそれぞれ`JarOutputStream`, `FileOutputStream`なのでこれらをつなげて ``` ObjectOutputStream os = new ObjectOutputStream(new JarOutputStream(new FileOutputStream(file))); ``` ...としたいところですが、このままですと`JarOutputStream`の作法に従っていないというエラーが出ますのでその部分を修正します。 そうすると以下の`compress`メソッドのような感じになるかと思います。 (また、本件タイトルに沿った「Javaで圧縮したファイルを解凍してオブジェクトとして読み込む」メソッドが`decompress`です。) ``` void compress(File jar, Asset target) throws IOException { try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jar))) { JarEntry ze = new JarEntry("asset"); jos.putNextEntry(ze); try (ObjectOutputStream os = new ObjectOutputStream(jos)) { os.writeObject(target); } } } Asset decompress(File jar) throws IOException, ClassNotFoundException { try (JarInputStream jis = new JarInputStream(new FileInputStream(jar))) { jis.getNextJarEntry(); try (ObjectInputStream is = new ObjectInputStream(jis)) { return (Asset) is.readObject(); } } } ``` 上記は無圧縮jarではないですが、敢えて圧縮しないのであればわざわざ`JarOutputStream`を使わず直接`FileOutputStream`を使うのが楽だと思います。 全体はここに挿入するには長くなってしまったので外部サイト(gist)に置いています。