不解压zip修改zip压缩包内容

一、需求

最近再开发过程中碰到一个问题,zip文件包中的一个文件内容存在不兼容的第三方依赖的数据,导致后续系统处理文件时,无法获取到准确的数据。

需求:在java代码中使用ZipInputStream,在不解压1.zip的情况下,将1.zip压缩包中的1.txt中的“我是谁”,替换为“我是大橙子”。

二、实现步骤

  1. 使用ZipInputStream读取ZIP文件。
  2. 遍历ZIP条目直到找到你想要修改的文件。
  3. 读取该文件的内容并进行替换。
  4. 使用ZipOutputStream创建一个新的ZIP文件。
  5. 将所有原始文件(除了被修改的那个)和修改后的文件写入新的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 {
// 原始ZIP文件路径
String zipFilePath = "1.zip";
// 目标文件名
String targetFileName = "1.txt";
// 替换前和后的字符串
String oldString = "我是谁";
String newString = "我是大橙子";

// 新的ZIP文件路径
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
ZipEntry newEntry = new ZipEntry(entry.getName());
zos.putNextEntry(newEntry);
zos.write(updatedContent);
zos.closeEntry();
} else {
// 如果不是目标文件,则直接复制到新ZIP文件
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