【问题标题】:Overwriting ZipEntrys覆盖 ZipEntry
【发布时间】:2011-07-03 11:56:41
【问题描述】:

简单的问题,

我正在将一系列文本文件写入 zip,只需将文件输出流包装在 zipoutputstream 中,然后再包装到打印机中。

public static int saveData(File outfile, DataStructure input) {
//variables
ArrayList<String> out = null;
FileOutputStream fileout = null;
ZipOutputStream zipout = null;
PrintWriter printer = null;

//parameter tests

try {
    fileout = new FileOutputStream(outfile);
    zipout = new ZipOutputStream(fileout);
    printer = new PrintWriter(zipout);
} catch (Exception e) {
    e.printStackTrace();
    return util.FILE_INVALID;
}

for(DataItem data : input){
    //process the data into a list of strings

    try {
    zipout.putNextEntry(new ZipEntry( dataFileName ));
    for(String s : out) {
        printer.println(s);
    }
    zipout.closeEntry();
    } catch (Exception e) {
    try {
        fileout.close();
    } catch (Exception x) {
        x.printStackTrace();
        return util.CRITICAL_ERROR;
    }
    e.printStackTrace();
    return util.CRITICAL_ERROR;
    }

}


try {
    fileout.close();
} catch (Exception e) {
    e.printStackTrace();
    return util.CRITICAL_ERROR;
}

return util.SUCCESS;

}

以前在我一直在开发的应用程序中,我刚刚保存到当前目录进行测试,我知道在文件已经存在的情况下,该文件将被覆盖(并且一直在利用这一点)。我不知道拉链的行为。它会覆盖同名的条目吗?或者它会简单地覆盖整个 zip 文件(这对我的目的来说很方便。

K.巴拉德

【问题讨论】:

    标签: java stream zip overwrite


    【解决方案1】:

    正如 Joel 所说,如果您尝试添加重复的 ZipEntry,您将收到异常。如果要替换当前条目,则需要将其删除并重新插入。 您可能需要执行以下操作来实现它:

        private ZipFile addFileToExistingZip(File zipFile, File versionFile) throws IOException{
        // get a temp file
        File tempFile = File.createTempFile(zipFile.getName(), null);
        // delete it, otherwise you cannot rename your existing zip to it.
        tempFile.delete();
    
        boolean renameOk=zipFile.renameTo(tempFile);
        if (!renameOk)
        {
            throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
        }
        byte[] buf = new byte[4096 * 1024];
    
        ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
    
        ZipEntry entry = zin.getNextEntry();
        while (entry != null) {
            String name = entry.getName();
            boolean toBeDeleted = false;
                if (versionFile.getName().indexOf(name) != -1) {
                    toBeDeleted = true;
                }
            if(!toBeDeleted){
                // Add ZIP entry to output stream.
                out.putNextEntry(new ZipEntry(name));
                // Transfer bytes from the ZIP file to the output file
                int len;
                while ((len = zin.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            }
            entry = zin.getNextEntry();
        }
        // Close the streams
        zin.close();
        // Compress the files
        InputStream in = new FileInputStream(versionFile);
        String fName = versionFile.getName();
        // Add ZIP entry to output stream.
        out.putNextEntry(new ZipEntry(fName));
        // Transfer bytes from the file to the ZIP file
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        // Complete the entry
        out.closeEntry();
        in.close();
        // Complete the ZIP file
        out.close();
        tempFile.delete();
    
        return new ZipFile(zipFile);
    }
    

    上面的代码适用于我需要向现有 zip 文件添加新 zip 条目的情况。如果该条目已经存在于 zip 中,则覆盖它。 欢迎对代码进行评论/改进! 谢谢!

    【讨论】:

      【解决方案2】:

      如果您尝试添加重复的 ZipEntry,您将遇到异常。如果要替换当前条目,则需要将其删除并重新插入。我怀疑您得到的异常与this one 大致相同。

      【讨论】:

      • 好吧,现在我一直在确保它的安全,只是手动检查并删除文件,然后再重新制作(zip 用于对程序的 3-20 个输出进行分组和压缩,保留旧的不参加本次会议将具有欺骗性)。在删除和重新插入的情况下,有没有办法在不解压缩和重新压缩的情况下删除条目?
      • 感谢您的确认。很遗憾,但不是灾难。
      猜你喜欢
      • 1970-01-01
      • 2011-06-11
      • 2012-01-28
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 2020-06-06
      • 2011-01-23
      相关资源
      最近更新 更多