1

私は、圧縮されたファイルを取得して解凍し、解凍されたすべてのファイルを含む新しいファイル/ディレクトリを返す方法に取り組んでいます。目標は、そのディレクトリを取得してそこから Excel ドキュメントを抽出し、それを私が作成した Workbook クラスに変換することです (これは完全に単体テストされ、正常に動作します)。問題は、次の例外が発生することです。

java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:215)
at java.util.zip.ZipFile.<init>(ZipFile.java:145)
at java.util.zip.ZipFile.<init>(ZipFile.java:159)
at com.atd.core.datamigrator.BulkImageUpload.createWorkbook(BulkImageUpload.java:54)
at com.atd.core.datamigrator.BulkImageUpload.importImages(BulkImageUpload.java:38)
at com.atd.core.datamigrator.BulkImageUpload.main(BulkImageUpload.java:236) 

これが私のコードです

private Workbook createWorkbook(File file) {
    File unZipedFile = unZip(file);
    File[] files = unZipedFile.listFiles();
    Workbook wBook = null;

    for (int i = 0; i < files.length; i++) {
        if (files[i].getName().contains(".xls")) {
            try {
                File f = files[i];
                ZipFile zip = new ZipFile(f);
                wBook = new Workbook(zip);
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;
        }
    }
    return wBook;
}

private File unZip(File input) {
    File output = new File("unzippedFile");
    OutputStream out = null;
    try {
        ZipFile zipFile = new ZipFile(input);
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            File entryDestination = new File(output, entry.getName());
            entryDestination.getParentFile().mkdirs();
            InputStream in = zipFile.getInputStream(entry);
            ZipInputStream zis = new ZipInputStream(in);
            out = new FileOutputStream(entryDestination);
            out.write(zis.read());
            out.flush();
            out.close();
        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return output;
}

解凍されたファイルを使用する代わりに File f = new File("some path") を使用すると、正常に動作するため、これが unzip メソッドの問題であることはわかっています。

また、ファイル I/O は私の得意分野ではありませんでした。

4

1 に答える 1

2

さて、これが問題だと思います:

ZipInputStream zis = new ZipInputStream(in);
out = new FileOutputStream(entryDestination);
out.write(zis.read());
out.flush();
out.close();

新しいファイルを作成し、それに1 バイトを書き込みます。これは、どの説明の有効な Excel ファイルにもなりません。finallyブロックを使用してストリームを閉じることもできませんが、それは別の問題です。あるストリームの内容を別のストリームにコピーするには、次のようなものが必要です。

byte[] buffer = new byte[8192];
int bytes;
while ((bytes = input.read(buffer)) > 0) {
    output.write(buffer, 0, bytes);
}

とはいえ、サードパーティのライブラリを使用してこの詳細をすべて非表示にする方がよいでしょう。たとえば、Guava とそのクラスを見ください。ByteStreamsFiles

ところで、一歩下がって、なぜこの問題を自分で見つけられなかったのかを考えてみる価値があります。たとえば、私が最初に行ったであろうことは、ファイルが解凍されたディレクトリを調べて、それらのファイルを開こうとすることでした。たくさんの 1 バイトのファイルを見るだけでも、ちょっとしたプレゼントになります。問題を診断しようとするときは、大きな問題を小さな問題に分割し、どの小さな問題に問題があるかを突き止めることが重要です。

于 2013-10-03T14:19:21.240 に答える