0

そのため、ファイルを zip アーカイブに追加することに興味があり、以前にこの質問をした数人のユーザーに出会い、別のユーザーがその問題の解決策として次のコード スニペットを提供しました。

    public static void updateZip(File source, File[] files, String path){
    try{
        File tmpZip = File.createTempFile(source.getName(), null);
        tmpZip.delete();
        if(!source.renameTo(tmpZip)){
            throw new Exception("Could not make temp file (" + source.getName() + ")");
        }
        byte[] buffer = new byte[4096];
        ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));
        for(int i = 0; i < files.length; i++){
            System.out.println(files[i].getName()+"being read");
            InputStream in = new FileInputStream(files[i]);
            out.putNextEntry(new ZipEntry(path + files[i].getName()));
            for(int read = in.read(buffer); read > -1; read = in.read(buffer)){
                out.write(buffer, 0, read);
            }
            out.closeEntry();
            in.close();
        }
        for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
            if(!zipEntryMatch(ze.getName(), files, path)){
                out.putNextEntry(ze);
                for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
                    out.write(buffer, 0, read);
                }
                out.closeEntry();
            }
        }
        out.close();
        tmpZip.delete();
    }catch(Exception e){
        e.printStackTrace();
    }
}

private static boolean zipEntryMatch(String zeName, File[] files, String path){
    for(int i = 0; i < files.length; i++){
        if((path + files[i].getName()).equals(zeName)){
            return true;
        }
    }
    return false;
}

このメソッドをテストするためのミニ プログラムを作成しました。これがすべての作業を行うメソッドです。

    private static void appendArchive() {
    String filename = "foo";
    File[] filelist = new File[10];
    int i = 0;
    String temp = "";
    while (!filename.trim().equals("")) {
        System.out
                .println("Enter file names to add, then enter an empty line");
        filename = getInput();
        filelist[i] = new File(filename, filename);
        System.out.println("Adding " + filelist[i].getName());

    }
    System.out
            .println("What is the name of the zip archive you want to append");
    File zipSource = new File(getInput() + ".zip", "testZip.zip");
    try {
        Archiver.updateZip(zipSource, filelist, "");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

このプログラムを実行しようとすると、このエラーが発生し、次のエラーが続きます。

java.lang.Exception: Could not make temp file (testZip.zip)

at Archiver.updateZip(Archiver.java:68)
at main.appendArchive(main.java:62)
at main.main(main.java:29)

渡していた zip ファイルが何らかの理由で開いていると見なされたため、Windows では名前の変更方法が機能していなかったので、代わりに現在表示されている zip ファイルのコンストラクターを使用してみました。ここで私が間違っていることは何ですか。私のテスト入力は、ファイルの 2 と 2 ( 2.zip に追加されます) です。ファイルはプログラムによって生成されるため、ディレクトリ関連の問題ではありません。ファイル

4

1 に答える 1

0

作品は私のために見つけます。の動作を確認したいと思うかもしれませんtmpZip.delete()

if (!tmpZip.exists() || tmpZip.delete()) {
    // ... Continue
} else {
    // ... File is locked
}

アップデート

私はコードをいじっていて、いくつかの追加の欠陥があります...

古いエントリを新しいファイルに追加すると、既存のZipEntryエントリが使用されます。結果の圧縮が異なる場合、これは失敗します。代わりにそれを使用して新しいZipEntry追加を作成する必要があります

ZipEntry ne = new ZipEntry(ze.getName());
out.putNextEntry(ne);
// Write bytes to file...
out.closeEntry();

最後に失敗することを意味しますZipInputStreamtmpZip.delete()

あなたはエラー処理が存在しないのと同じです...

ZipInputStream zin = null;
ZipOutputStream out = null;
try {
    // Append zip ...
} finally {
    try {
        zin.close();
    } catch (Exception exp) {
    }
    try {
        out.close();
    } catch (Exception exp) {
    }
}

将来のファイルロックを防ぎます(IOException個人的には呼び出されたものにスローする必要があると信じているため、意図的にキャッチしませんでした)

終了するまで、既存の zip ファイルを上書きしないでください。新しい zip ファイルの一時ファイルを作成し、そこにすべてのファイルを書き込み、既存のファイルを追加し、完了したら、既存のファイルを一時ファイルに置き換える必要があります。

これは、何か問題が発生した場合でも、既存の zip ファイルを破棄していないことを意味します。

私見では

于 2012-08-22T00:55:39.607 に答える