Changing the contents of the recording file in the zipfile

I want to update the content of a text file that is inside a zip file.

I can't seem to figure out how to do this and the code below is not working correctly.

Thanks for your help!

import java.util.zip.ZipFile
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

String zipFileFullPath = "C:/path/to/myzipfile/test.zip"

ZipFile zipFile = new ZipFile(zipFileFullPath) 
ZipEntry entry = zipFile.getEntry ( "someFile.txt" )

if(entry){
    InputStream input = zipFile.getInputStream(entry)
    BufferedReader br = new BufferedReader(new InputStreamReader(input, "UTF-8"))

    String s = null
    StringBuffer sb = new StringBuffer()

    while ((s=br.readLine())!=null){
         sb.append(s)
    }

    sb.append("adding some text..")


     ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileFullPath))
     out.putNextEntry(new ZipEntry("someFile.txt"));

     int length


     InputStream fin = new ByteArrayInputStream(sb.toString().getBytes("UTF8"))

     while((length = fin.read(sb)) > 0)
     {
            out.write(sb, 0, length)
     }             

     out.closeEntry()

}

      

+3


source to share


2 answers


Just some minor changes to @ Opal's answer, I just:

  • Used groovy methods where possible
  • packed into a method

Groovy Snippet



void updateZipEntry(String zipFile, String zipEntry, String newContent){
    def zin = new ZipFile(zipFile)
    def tmp = File.createTempFile("temp_${System.nanoTime()}", '.zip')
    tmp.withOutputStream { os ->
        def zos = new ZipOutputStream(os)
        zin.entries().each { entry ->
            def isReplaced = entry.name == zipEntry
            zos.putNextEntry(isReplaced ? new ZipEntry(zipEntry) : entry)
            zos << (isReplaced ? newContent.getBytes('UTF8') : zin.getInputStream(entry).bytes )
            zos.closeEntry()
        }
        zos.close()
    }
    zin.close()
    assert new File(zipFile).delete()
    tmp.renameTo(zipFile)
}

      

Using

updateZipEntry('/tmp/file.zip', 'META-INF/web.xml', '<foobar>new content!</foobar>')

      

+4


source


What exactly isn't working? Is there an exception?

As far as I know, it is not possible to modify the zip file in place. The following script overwrites the file and, if the desired write is processed, changes it.

import java.util.zip.*

def zipIn = new File('lol.zip')
def zip = new ZipFile(zipIn)
def zipTemp = File.createTempFile('out', 'zip')
zipTemp.deleteOnExit()
def zos = new ZipOutputStream(new FileOutputStream(zipTemp))
def toModify = 'lol.txt'

for(e in zip.entries()) {
    if(!e.name.equalsIgnoreCase(toModify)) {
        zos.putNextEntry(e)
        zos << zip.getInputStream(e).bytes
    } else {
        zos.putNextEntry(new ZipEntry(toModify))
        zos << 'lollol\n'.bytes
    }
    zos.closeEntry()
}

zos.close()
zipIn.delete()
zipTemp.renameTo(zipIn)

      

UPDATE



I was wrong. It is possible to modify the zip file in place, but your solution will omit other files that have been zipped. The output file will only contain one file - the file you want to modify. I am also guessing that the You file was corrupted due to the fact that you did not call close()

on out

.

Below you script is slightly modified (more groovier):

import java.util.zip.*

def zipFileFullPath = 'lol.zip'
def zipFile = new ZipFile(zipFileFullPath) 
def entry = zipFile.getEntry('lol.txt')

if(entry) {
   def input = zipFile.getInputStream(entry)
   def br = new BufferedReader(new InputStreamReader(input, 'UTF-8'))
   def sb = new StringBuffer()

   sb << br.text
   sb << 'adding some text..'

   def out = new ZipOutputStream(new FileOutputStream(zipFileFullPath))
   out.putNextEntry(new ZipEntry('lol.txt'))

   out << sb.toString().getBytes('UTF8')
   out.closeEntry()
   out.close()
}

      

+3


source







All Articles