0

このコードを使用して zip アーカイブからファイルを抽出しています (すべての catch ステートメントとその他の初期化ステートメントを省略しています)。

zipInputStream = new ZipInputStream(new FileInputStream(file));
zipFile = new ZipFile(file);
for (Enumeration<?> em = zipFile.entries(); em.hasMoreElements();) {
    String extractedFileName = em.nextElement().toString();
    ZipEntry outerZipEntry = zipInputStream.getNextEntry();
    if (outerZipEntry.getName().contains(searchString)) {
        extractedFile = new File(outputDir + outerZipEntry.getName());
        out = new FileOutputStream(outputDir + extractedFileName);
        byte[] buf = new byte[1024];
        int len;
        while ((len = zipInputStream.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        break;
     } 
}

このコードは、たとえば /archive.zip/file_i_need.txt でファイルを抽出するときに正常に機能します。

しかし、/archive.zip/folder1/file_i_need.txt からファイルを抽出しようとすると、readLine() を使用してファイルを読み取ろうとすると、例外 java.lang.NullPointerException が発生します。

String line = null ;
BufferedReader input = new BufferedReader(newFileReader(extractedFile)) ;
while( (line = input.readLine() ) != null ) {
    ...
}

両方のケースでテストしましたが、ファイルがフォルダー内にある場合、このコードは機能しないようです。

お勧めできる提案はありますか?

ありがとう!

4

3 に答える 3

1
extractedFile = new File(outputDir + outerZipEntry.getName());

問題は、エントリ名に作成していないパス要素が含まれている可能性があることを考慮していないことです。単にファイルへの書き込みを試みます。なぜこれでエラーが発生しないのか、よくわかりません。

Windowsでこれらのファイルを書いていますか?? これにより、ファイルシステムのようなファイルが作成folder1/file_i_need.txtされますが、これはおそらくあるレベルでは無効です:P

からファイル名を抽出してみてくださいZipEntry

String name = outerZipEntry.getName();
name = name.substring(name.lastIndexOf("/") + 1);

明らかに、名前に実際に「/」が最初に含まれていることを確認してください;)

アップデート

私がそれをしている間、これは間違っているように見えます

extractedFile = new File(outputDir + outerZipEntry.getName());
out = new FileOutputStream(outputDir + extractedFileName);

基本的にあなたの言い分outputDir + outerZipEntry.getName() + (outputDir + outerZipEntry.getName())

アップデート

これを Windows でテストしたFileNotFoundExceptionところ、存在しないパスにファイルを書き込もうとするとエラーが発生しました

Macでもテストしたところ、FileNotFoundException

エラー処理が何をしているのかわかりませんが、間違っています。

于 2012-08-13T20:19:31.883 に答える
1

あなたの問題は、 FileOutputStream をオンラインで開けないことだと思いますout = new FileOutputStream(outputDir + extractedFileName);。たとえば、 が で、outputDir が である場合extractedFileNameは、でストリームを開こうとしているため、ストリームを開くことはできません。そのようなディレクトリは存在せず、out は null になります。私のコメントで言及していた投稿には解凍操作があり、zip ファイル内のディレクトリ エントリの特別な処理を確認できます。folder1/file_i_need.txtC:/OutputDirC:/OutputDirfolder1/file_i_need.txt

于 2012-08-13T20:14:01.787 に答える
0

2 つの異なる方法で zip エントリを繰り返し処理しています。

反復 1:

for (Enumeration<?> em = zipFile.entries(); em.hasMoreElements();) {

反復 2:

ZipEntry outerZipEntry = zipInputStream.getNextEntry();

どちらか一方を行うだけです。ZipFileAPI または APIのいずれかを使用しZipInputStreamます。NullPointerExceptionそれがどこから来ているのか、私は強く疑っています。

于 2012-08-13T19:28:50.443 に答える