附加zip存档调试

所以我有兴趣将文件附加到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  -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)。 它不应该是任何与目录相关的问题,因为文件是由程序生成的。 文件

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

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

UPDATE

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

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

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

你永远不会关闭ZipInputStream ,这意味着tmpZip.delete()将失败。

你的error handling是不存在的……

 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文件。

恕我直言