【问题标题】:Copy a file into a double archive in Java (a zip file which is in another zip file)将文件复制到 Java 中的双重存档中(另一个 zip 文件中的 zip 文件)
【发布时间】:2019-04-16 12:54:21
【问题描述】:

我有一个耳朵存档,“archive.ear”。这个档案包含一个战争文件,“archive.war”。在这个文件中,我想用磁盘上存在的新文件替换文件“/myFile.properties”。

新文件的内容保存在名为“file”的 java.io.File 对象中。我将来自“/myFile.properties”的输出流从存档中保存在 java.io.OutputStream 对象中。之后,我尝试使用

org.apache.commons.io.FileUtils.copy(File input, OutputStream output)

目前的代码是:

// Java method from extracting the output stream
public OutputStream getOutputStream(OutputStream out, String entry) throws IOException {
    ZipOutputStream zos = new ZipOutputStream(out);
    ZipEntry zipEntry = new ZipEntry(entry);
    while (zipEntry != null) {
        if (zipEntry.toString().equals(entry)) {
            return zos;
        }
    }
    throw new IllegalStateException("No entry '" + entry + "' found");
}

// copy the file content to output stream
// extract output stream "archive.war" from "archive.ear"
OutputStream warOs = zu.getOutputStream(new FileOutputStream("archive.ear"), "archive.war");

// extract output stream "<path>/myFile.properties" from "archive.war"
OutputStream myFileOutput = zu.getOutputStream(warOs, "<path>/myFile.properties" );  

FileUtils.copyFile(file, myFileOutput);

我也尝试使用,插入copyFile():

myFileOutput.write(getBytesFromFile(file));

方法“getBytesFromFile()”从文件对象返回一个字节数组。

当我打开战争档案时,我希望“myFile.properties”具有新内容,该内容位于 java 对象“文件”中。该文件具有正确的内容。 结果是 ZipException:

Exception in thread "main" java.util.zip.ZipException: no current ZIP entry
       at java.util.zip.ZipOutputStream.write(Unknown Source)
       at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2315)
       at org.apache.commons.io.IOUtils.copy(IOUtils.java:2270)
       at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2291)
       at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1094)
       at main.Main.main(Main.java:69)

【问题讨论】:

    标签: java copy archive


    【解决方案1】:

    您不能(轻松)使用 Java 操作现有的 zip 文件。 您必须绕道而行。

    1. 将当前的“archive.ear”打开为 ZipInputStream。
    2. 打开一个新的“archive.ear.new”作为 ZipOutputStream。
    3. 将所有 ZipEntries 从 1. 转移到 2.
      1. 当您进入您的条目“archive.war”时
      2. 为其打开一个新的 ZipInputStream
      3. 为 2 的条目打开一个新的 ZipOutputStream。
      4. 传输除“myFile.properties”之外的所有 ZipEntries
      5. 为条目传输“myFile.properties”的内容
      6. 刷新您的 ZipOutputStream,关闭条目
    4. 将新文件重命名为旧文件

    【讨论】:

    • 我正在尝试这个,我在第 5 步遇到了一些问题 - 为条目传输 myFile.properties 的内容。当代码到达“zos.putNextEntry(zipEntry)”行时(zos 是一个 ZipOutputStream 对象),它会抛出一个 ZipException,并显示消息“无效的条目大小(预期为 104,但得到 0 字节)”
    • 您必须为更改的条目设置正确的大小。如果你有一个 java.io.File 只需获取 file.length() 并设置它:zipEntry.setSize((int)file.length()); 另一种方法是创建一个新的 ZipEntry 并复制除大小之外的所有内容。
    • 我尝试在我的个人计算机上运行相同的方法。唯一的区别是我没有复制原始的 .war 和 .ear 档案,而是从我的计算机上改编了一些现有的档案。它工作得很好。在这一刻,我的问题是为什么我的工作站上的程序不起作用并引发异常。代码是一样的。两者都是用 Java8 编译的。
    • 听起来不太好。它可能与操作系统有关,可能是 zip 压缩不同或有问题。可能文件已损坏或有文件锁定或其他干扰。
    猜你喜欢
    • 2019-03-03
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2015-04-23
    • 2021-04-29
    • 2016-01-24
    相关资源
    最近更新 更多