附加zip归档调试 [英] Appending zip archive debugging

查看:143
本文介绍了附加zip归档调试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有兴趣将文件附加到zip存档,我遇到了一些以前提出这个问题的用户,另外一个用户给出了这个代码段来解决这个问题:

So I was interested in appending files to a zip archive and I came across a few users who asked this question before and another user gave this code snippet as a solution to that problem:

    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;
}

我创建了一个迷你程序来测试这种方法,这是一种方法做所有的工作:

I created a mini program to test out this method and this is the method that does all the work:

    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();
    }
}

每当我尝试运行这个程序,我得到这个错误,然后是下一个:

Whenever I try to run this program I get this error, followed by the next one:

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。它不应该是任何目录相关的问题,因为文件是由程序生成的。

I suspected that the zip file I was passing was considered open for some reason, and so the rename method wasn't working on windows so I instead tried using the constructor for zip file you see now. What exactly am I doing wrong here. My test input is 2 for the file, and 2(which is appended to 2.zip ). It shouldnt be any directory related issues since the files are generated by the program.

推荐答案

工作为我找到。我怀疑你可能想检查 tmpZip.delete()的操作。

Works find for me. I suspect you might want to check the operation of tmpZip.delete().

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

更新

我一直在玩代码,还有一些额外的缺陷...

I've been playing around with the code and there are some additional flaws...

将旧条目添加到新文件中时,您正在使用现有的 ZipEntry 条目。如果产生的压缩不同,这将失败。您应该创建一个新的 ZipEntry 添加使用,而不是

When adding in the old entries to the new file, you are using the existing ZipEntry entry. This will fail if the resulting compression is different. You should create a new ZipEntry add use that instead

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

你永远不会关闭 ZipInputStream code> tmpZip.delete()最终将失败。

You never close the ZipInputStream which means tmpZip.delete() at the end will fail.

你的错误处理是不存在的... 。

You're error handling is next to non existent...

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

将阻止将来的文件锁(我已经故意没有抓住 IOException ,因为我个人认为应该被抛回被叫)

Will prevent future file locks (I've deliberately not caught the IOException as I personally believe it should be thrown back to the called)

您不应该覆盖已完成的现有zip文件UNTIL。您应该为新的zip文件创建一个临时文件,将所有文件写入其中,附加现有文件,一旦完成,将现有文件替换为临时文件。

You shouldn't overwrite the existing zip file UNTIL you have finished. You should create a temporary file for the new zip file, write all the files into it, append the existing files and once your done, replace the existing file with the temporary one.

这意味着,如果出现问题,您没有销毁现有的zip文件。

This means, if something should go wrong, you've not destroyed the existing zip file.

IMHO

这篇关于附加zip归档调试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆