2014-10-04 160 views
3

我想更新位于zip文件内的文本文件的内容。修改zipfile条目的文件内容

我无法找到如何做到这一点,下面的代码无法正常工作。

感谢您的帮助!

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

什么是不工作?有没有抛出异常?

据我所知,不可能修改一个zip文件原位。以下脚本重写该文件,并在需要时处理输入 - 修改它。

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

我是不正确的。可以修改原始文件,但您的解决方案将省略压缩的其他文件。输出文件将只包含一个文件 - 您想要修改的文件。我还假设你的文件因out没有调用close()而被破坏。

下面是你的脚本稍作修改(更多更巧妙的):

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() 
} 
+0

感谢您的帮助蛋白石。你的第一个解决方案看起来不错,但由于某种原因没有任何反应,zip文件似乎根本没有改变。 – user955732 2014-10-04 14:20:22

+0

压缩文件不会被删除。临时文件看起来不错。 – user955732 2014-10-04 14:52:32

+0

我已经在Mac OS上测试过。请让我知道它是否解决了问题。我可以再检查一次。 – Opal 2014-10-04 22:40:49

4

只是一些很小的改动就@欧泊的答案,我只是:

  • 使用常规方法在可能的情况
  • 打包在一个方法中

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) 
} 

使用

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