常见的压缩文件格式有zip、tar、rar(包含rar4)、7z、xz等,针对不同的压缩格式解压需要有不同的代码实现,适配工作比较大,故将常见的压缩文件解压逻辑封装为工具类,供后续使用。

  • 引入依赖:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding -->
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding</artifactId>
<version>16.02-2.01</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding-all-platforms -->
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding-all-platforms</artifactId>
<version>16.02-2.01</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.27.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.tukaani/xz -->
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.9</version>
</dependency>
  • 解压缩工具类:DecompressUtil.java
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package site.zhaoyangjue.decompression.utils;

import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

public class DecompressUtil {
/**
* 解压常见的压缩文件:zip|tar|rar(包含rar4和rar5)|7z
* @param file 文件
* @param targetPath 保存路径,为目录
*/
public static void decompressCommonFile(File file, String targetPath){
RandomAccessFileInStream inStream = null;
IInArchive inArchive = null;
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
inStream = new RandomAccessFileInStream(randomAccessFile);
inArchive = SevenZip.openInArchive(null, inStream);
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
ISimpleInArchiveItem[] archiveItems = simpleInArchive.getArchiveItems();
File outFile = new File(targetPath);
for (ISimpleInArchiveItem item : archiveItems) {
RandomAccessFileOutStream rafo = null;
try {
File tempFile;
if (item.isFolder()) {
new File(outFile , item.getPath()).mkdirs();
continue;
} else {
tempFile = new File(outFile , item.getPath());
if (! tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdirs();
}
}
rafo = new RandomAccessFileOutStream(new RandomAccessFile(tempFile , "rw"));
item.extractSlow(rafo);
} finally {
if (rafo != null) {
rafo.close();
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(inStream);
IOUtils.closeQuietly(inArchive);
}
}

/**
* 解压缩xz格式的文件
* @param file 文件
* @param targetPath 保存路径,为目录
*/
public static void decompressXZFile(File file, String targetPath){
try(FileInputStream fis = new FileInputStream(file);
XZCompressorInputStream xzIn = new XZCompressorInputStream(fis);
TarArchiveInputStream tarIn = new TarArchiveInputStream(xzIn)){
ArchiveEntry entry;
while ((entry = tarIn.getNextEntry()) != null) {
if (entry.isDirectory()) {
File directory = new File(targetPath,entry.getName());
directory.mkdirs();
} else {
File outputFile = new File(targetPath,entry.getName());
FileOutputStream fos = new FileOutputStream(outputFile);
byte[] buffer = new byte[2048];
int length;
while ((length = tarIn.read(buffer)) != -1) {
fos.write(buffer,0,length);
}
fos.close();
}
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

/**
* 将MultipartFile转换为file
* @param file MultipartFile
* @return 转换之后的file
* @throws Exception
*/
public static File multipartFileToFile(MultipartFile file) throws Exception {

File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
ins = file.getInputStream();
toFile = new File(file.getOriginalFilename());
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}

private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
  • 备注:
1
2
原始压缩包会保存在项目的根目录下,如后续无额外的操作,则可在外层调用处删除。
可先将接口接受到的MultipartFile转换为File,再行调用decompressCommonFile方法或decompressXZFile方法。