2014-10-04 155 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>')