将文件复制到Java中的双存档(另一个zip文件中的zip文件)

将文件复制到Java中的双存档(另一个zip文件中的zip文件),java,copy,archive,Java,Copy,Archive,我有一个耳朵档案,“archive.ear”。此存档包含一个war文件“archive.war”。在这个文件中,我想用磁盘上的新文件替换文件“/myFile.properties” 新文件的内容保存在名为“file”的java.io.file对象中。我将归档文件中“/myFile.properties”的输出流保存在java.io.OutputStream对象中。在那之后,我试着用 org.apache.commons.io.FileUtils.copy(File input, OutputSt

我有一个耳朵档案,“archive.ear”。此存档包含一个war文件“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);
方法“getBytesFromFile()”从文件对象返回字节数组

当我打开war归档文件时,我希望“myFile.properties”包含新内容,它位于java对象“file”中。此文件具有正确的内容。 结果是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操作现有的zip文件。 你必须以迂回的方式来做这件事

  • 以ZipInputStream的形式打开当前的“archive.ear”
  • 以ZipOutputStream的形式打开一个新的“archive.ear.new”
  • 从1中转移所有的ZipEntries。到2。
  • 当你进入你的条目“存档。战争”
  • 为它打开一个新的ZipInputStream
  • 为2的条目打开新的ZipoutStream
  • 传输除“myFile.properties”之外的所有ZipEntries
  • 传输条目的“myFile.properties”内容
  • 刷新ZipOutputStream,关闭入口
  • 将新文件重命名为旧文件

  • 我正在尝试此操作,但在第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压缩不同或有问题。可能文件已损坏,或有文件锁或其他干扰。
    
    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)