一、需求
最近再开发过程中碰到一个问题,zip文件包中的一个文件内容存在不兼容的第三方依赖的数据,导致后续系统处理文件时,无法获取到准确的数据。
需求:在java代码中使用ZipInputStream,在不解压1.zip的情况下,将1.zip压缩包中的1.txt中的“我是谁”,替换为“我是大橙子”。
二、实现步骤
- 使用
ZipInputStream读取ZIP文件。 
- 遍历ZIP条目直到找到你想要修改的文件。
 
- 读取该文件的内容并进行替换。
 
- 使用
ZipOutputStream创建一个新的ZIP文件。 
- 将所有原始文件(除了被修改的那个)和修改后的文件写入新的ZIP文件。
 
三、实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
   | import java.io.*; import java.util.zip.*;
  public class Test {     public static void main(String[] args) throws IOException {                  String zipFilePath = "1.zip";                  String targetFileName = "1.txt";                  String oldString = "我是谁";         String newString = "我是大橙子";
                   String newZipFilePath = "2.zip";
          try (ZipFile zipFile = new ZipFile(zipFilePath);              FileOutputStream fos = new FileOutputStream(newZipFilePath);              ZipOutputStream zos = new ZipOutputStream(fos)) {
              Enumeration<? extends ZipEntry> entries = zipFile.entries();             while (entries.hasMoreElements()) {                 ZipEntry entry = entries.nextElement();                 InputStream is = zipFile.getInputStream(entry);
                  if (entry.getName().equals(targetFileName)) {                                          String content = new String(readAllBytes(is), StandardCharsets.UTF_8);                     content = content.replace(oldString, newString);                     byte[] updatedContent = content.getBytes(StandardCharsets.UTF_8);
                                           ZipEntry newEntry = new ZipEntry(entry.getName());                     zos.putNextEntry(newEntry);                     zos.write(updatedContent);                     zos.closeEntry();                 } else {                                          zos.putNextEntry(new ZipEntry(entry.getName()));                     byte[] buffer = new byte[1024];                     int length;                     while ((length = is.read(buffer)) > 0) {                         zos.write(buffer, 0, length);                     }                     zos.closeEntry();                 }                 is.close();             }         }     }
      private static byte[] readAllBytes(InputStream is) throws IOException {         ByteArrayOutputStream baos = new ByteArrayOutputStream();         byte[] buffer = new byte[1024];         int length;         while ((length = is.read(buffer)) != -1) {             baos.write(buffer, 0, length);         }         return baos.toByteArray();     } }
   | 
 
这段代码首先打开原始的ZIP文件,并创建一个新的ZIP文件。然后,它遍历ZIP文件中的每个条目,如果条目名称与要修改的文件名匹配,它会读取文件内容,执行字符串替换,并将更新后的内容写入新ZIP文件。对于其他文件,它们会被原封不动地复制到新ZIP文件中。
文件编码为UTF-8,如果文件使用了不同的编码,请相应地更改StandardCharsets.UTF_8。