You should use FileSystem API instead and create a ZipFileSystem out of your 
zipfile. The filesystems API permits you to work on both input operations and 
output operations of the same file.

        String zipFilePath = "asdf.zip";
        try (FileSystem fs = FileSystems.newFileSystem(Path.of(zipFilePath), 
null)) {
            Path source = fs.getPath("/abc.txt"); 
            Files.delete(source);
            try(BufferedOutputStream zout = new 
BufferedOutputStream(fs.provider().newOutputStream(source))) {
                zout.write(new byte[1024]);
            }; 
        }

FileSystem API got introduced in java 7, so compatibility must not be an issue 
to you.


-----Original Message-----
From: Darryl L. Pierce <[email protected]> 
Sent: Wednesday, October 20, 2021 22:22
To: [email protected]
Subject: Appending new entry to an existing archive (zip and 7zip)

I'm trying to add functionality to a project to append an entry to an existing 
archive, but am not having success. Specifically, the feature seeks to add or 
replace an existing entry in an archive. What I've attempted so far is:

---8<[snip]---
  @Override
  protected void doSaveEntry(
      final String archiveFilename, final String entryName, final byte[] 
content) {
    try (ZipArchiveOutputStream archive =
        new ZipArchiveOutputStream(new
FileOutputStream(archiveFilename, true))) {
      log.trace("Creating archive entry");
      final ZipArchiveEntry archiveEntry = new ZipArchiveEntry(entryName);
      archiveEntry.setSize(content.length);
      log.trace("Adding entry to archive");
      archive.putArchiveEntry(archiveEntry);
      log.trace("Copying content to entry");
      IOUtils.copy(new ByteArrayInputStream(content), archive);
      archive.closeArchiveEntry();
      archive.finish();
    } catch (IOException error) {
      log.trace("Failed to add entry to archive", error);
    }
  }
---8<[snip]---

After running the code, I try to read from the archive. What I get then is the 
following exception:

---8<[snip]---

java.io.IOException: Error on ZipFile
/Users/mcpierce/Repositories/comixed/comixed-adaptors/target/test-classes/save-example.cbz

    at 
org.apache.commons.compress.archivers.zip.ZipFile.<init>(ZipFile.java:383)
    at 
org.apache.commons.compress.archivers.zip.ZipFile.<init>(ZipFile.java:261)
    at 
org.apache.commons.compress.archivers.zip.ZipFile.<init>(ZipFile.java:230)
    at 
org.apache.commons.compress.archivers.zip.ZipFile.<init>(ZipFile.java:213)
    at 
org.apache.commons.compress.archivers.zip.ZipFile.<init>(ZipFile.java:174)
    at 
org.comixedproject.adaptors.archive.NewZipArchiveAdaptor.doOpenArchive(NewZipArchiveAdaptor.java:50)
    at 
org.comixedproject.adaptors.archive.NewZipArchiveAdaptor.doOpenArchive(NewZipArchiveAdaptor.java:42)
    at 
org.comixedproject.adaptors.archive.AbstractNewArchiveAdaptor.openArchive(AbstractNewArchiveAdaptor.java:37)
    at 
org.comixedproject.adaptors.archive.NewZipArchiveAdaptorTest.testSaveEntry(NewZipArchiveAdaptorTest.java:95)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
    at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at 
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at 
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at 
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at 
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at 
org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at 
org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at 
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at 
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at 
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at 
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at 
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at 
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at 
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at 
com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.io.IOException: Central directory is empty, can't expand 
corrupt archive.
    at 
org.apache.commons.compress.archivers.zip.ZipFile.populateFromCentralDirectory(ZipFile.java:721)
    at 
org.apache.commons.compress.archivers.zip.ZipFile.<init>(ZipFile.java:376)
    ... 39 more
---8<[snip]---

What am I doing wrong and how do I fix it so that the new entry is appended to 
the archive?


--
Darryl L. Pierce <[email protected]>
"Le centre du monde est partout." - Blaise Pascal "Let's try and find some 
point of transcendence and leap together." - Gord Downie

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to