文件打包

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
/**
* 文件打包
* 将传递过来的文件列表写入zip文件
* @param fileList 要打包的文件
* @param zipFileName 打包后的文件名
* @throws IOException
*/
public static void downZipManyFile(List<File> fileList, String zipFileName) throws IOException {

BufferedInputStream br = null;//输入流
ZipOutputStream out = null; // 压缩文件输出流
ZipEntry zip = null; //用于表示 ZIP 文件条目。
int size =-1;

byte[] buffer = new byte[2048];// 定义缓冲区
if(fileList.size()>0){
out = new ZipOutputStream(new FileOutputStream(zipFileName));
for (int i = 0; i < fileList.size(); i++) {
File f =fileList.get(i);
zip = new ZipEntry(f.getName());
out.putNextEntry(zip);
br = new BufferedInputStream(new FileInputStream(f));
while((size=br.read(buffer))!=-1){
out.write(buffer,0,size);
out.flush();
}
}

zip.clone();
br.close();
out.close();
}
}

多种压缩文件解压

包含实现对.zip、.rar、.7z、.tar、.tar.gz的解压

Maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- .7z -->
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding</artifactId>
<version>9.20-2.00beta</version>
</dependency>
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding-all-platforms</artifactId>
<version>9.20-2.00beta</version>
</dependency>
<!-- .7z end -->

<!-- .tar/.tar.gz -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.4</version>
</dependency>
<!-- .tar/.tar.gz end -->

代码实现

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/*功能:多种格式压缩文件解压(.zip、.rar、.7z、.tar、.tar.gz)*/

//使用gbk编码避免zip解压中文文件名乱码
private static final String CHINESE_CHARSET = "gbk";
//文件读取缓冲区大小
private static final int CACHE_SIZE = 1024;
//系统类型
private static final String WINDOWS="windows";
private static final String LINUX="linux";

/**
* 多种格式压缩文件解压
* @param srcFileName 源文件全路径
* @param destDir 解压后存储路径
*/
public static void deCompress(String srcFileName, String destDir){

//存储路径不存在则创建
File dFile=new File(destDir);
if (!dFile.exists()) {
dFile.mkdirs();
}

if (srcFileName.toLowerCase().endsWith(".zip")) {
unZip(srcFileName, destDir);
} else if (srcFileName.toLowerCase().endsWith(".rar")) {
unRar(srcFileName, destDir);
}else if (srcFileName.toLowerCase().endsWith(".7z")) {
un7Z(srcFileName, destDir);
}else if (srcFileName.toLowerCase().endsWith(".tar")) {
unTar(srcFileName, destDir);
}else if (srcFileName.toLowerCase().endsWith(".tar.gz")) {
unTarGz(srcFileName, destDir);
}

}

/**
* .zip格式解压
* @param srcFileName 源文件全路径
* @param destDir 解压后存储路径
*/
public static void unZip(String srcFileName, String destDir) {
try {
//解决中文乱码
ZipFile zip = new ZipFile(srcFileName, Charset.forName(CHINESE_CHARSET));
//循环遍历
for (Enumeration<? extends ZipEntry> entries = zip.entries();
entries.hasMoreElements();) {
ZipEntry entry = entries.nextElement();
String zipEntryName = entry.getName();
InputStream in = zip.getInputStream(entry);
String outPath = (destDir +"/"+ zipEntryName).replaceAll("\\*", "/");

// 判断路径是否存在,不存在则创建文件路径
File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
if (!file.exists()) {
file.mkdirs();
}

// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
if (new File(outPath).isDirectory()) {
continue;
}

FileOutputStream out = new FileOutputStream(outPath);
byte[] buf = new byte[CACHE_SIZE];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}

in.close();
out.close();
}

}catch (Exception e){
e.printStackTrace();
}
}

/**
* .rar格式解压
* @param srcFileName 源文件全路径
* @param destDir 解压后存储路径
*/
public static void unRar(String srcFileName, String destDir){
String cmd = null;
String unRarCmd = null;
try {
if (systemType().equals(WINDOWS)) {
//解压模板命令
unRarCmd = "F:\\Program Files (x86)\\WinRAR\\WinRAR.exe x ";
//构建解压命令
cmd = unRarCmd + srcFileName + " " + destDir;
} else if (systemType().equals(LINUX)) {
//解压模板命令
unRarCmd = "unrar x ";
//构建解压命令
cmd = unRarCmd + srcFileName + " " + destDir;
}
//构造运行对象
Runtime rt = Runtime.getRuntime();
//在单独的进程中执行指定的字符串命令。
rt.exec(cmd);

} catch (Exception e) {
e.printStackTrace();
}
}

/**
* .7z格式解压
* @param srcFileName 源文件全路径
* @param destDir 解压后存储路径
*/
public static void un7Z(String srcFileName, String destDir){

RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null;
try {
randomAccessFile = new RandomAccessFile(srcFileName, "r");
inArchive = SevenZip.
openInArchive(null,new RandomAccessFileInStream(randomAccessFile));

ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();

//遍历
for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
int[] hash = new int[] { 0 };
if (!item.isFolder()) {
ExtractOperationResult result;
long[] sizeArray = new long[1];

//tarFile是遍历的每一个文件
File tarFile=new File(destDir+File.separator+item.getPath());
//tarFile父目录不存在,则创建
if (!tarFile.getParentFile().exists()) {
tarFile.getParentFile().mkdirs();
}
//创建tarFile文件
tarFile.createNewFile();

result = item.extractSlow(new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {
FileOutputStream fos=null;
try {
fos = new FileOutputStream(tarFile.getAbsolutePath());
//将数据写入fos
fos.write(data);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

hash[0] ^= Arrays.hashCode(data);
sizeArray[0] += data.length;
return data.length;
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
if (inArchive != null) {
try {
inArchive.close();
} catch (SevenZipException e) {
e.printStackTrace();
}
}
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

/**
* .tar格式解压
* @param srcFileName 源文件全路径
* @param destDir 解压后存储路径
*/
public static void unTar(String srcFileName, String destDir){
FileInputStream fis = null;
OutputStream fos = null;
TarInputStream tarInputStream = null;
try {
fis = new FileInputStream(new File(srcFileName));
tarInputStream = new TarInputStream(fis, CACHE_SIZE);

TarEntry entry = null;
while(true){
entry = tarInputStream.getNextEntry();
if( entry == null){
break;
}
if(entry.isDirectory()){
System.out.println(entry.getName());
createDirectory(destDir, entry.getName()); // 创建子目录
}else{
fos = new FileOutputStream(new File(destDir + File.separator +
entry.getName()));
int count;
byte data[] = new byte[CACHE_SIZE];
while ((count = tarInputStream.read(data)) != -1) {
fos.write(data, 0, count);
}
fos.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fis != null){
fis.close();
}
if(fos != null){
fos.close();
}
if(tarInputStream != null){
tarInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* .tar.gz解压
* @param srcFileName 源文件全路径
* @param destDir 解压后存储路径
*/
public static void unTarGz(String srcFileName, String destDir){
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
GZIPInputStream gzipIn = null;
TarInputStream tarIn = null;
OutputStream out = null;
try {
fileInputStream = new FileInputStream(new File(srcFileName));
bufferedInputStream = new BufferedInputStream(fileInputStream);
gzipIn = new GZIPInputStream(bufferedInputStream);
tarIn = new TarInputStream(gzipIn, CACHE_SIZE);

TarEntry entry = null;
while((entry = tarIn.getNextEntry()) != null){
if(entry.isDirectory()){ // 是目录
createDirectory(destDir, entry.getName()); // 创建子目录
}else{ // 是文件
File tempFIle = new File(destDir + File.separator + entry.getName());
createDirectory(tempFIle.getParent() + File.separator, null);
out = new FileOutputStream(tempFIle);
int len =0;
byte[] b = new byte[CACHE_SIZE];

while ((len = tarIn.read(b)) != -1){
out.write(b, 0, len);
}
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(out != null){
out.close();
}
if(tarIn != null){
tarIn.close();
}
if(gzipIn != null){
gzipIn.close();
}
if(bufferedInputStream != null){
bufferedInputStream.close();
}
if(fileInputStream != null){
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* 构建目录
* @param outputDir 输出目录
* @param subDir 子目录
*/
private static void createDirectory(String outputDir, String subDir){
File file = new File(outputDir);
if(!(subDir == null || subDir.trim().equals(""))) {//子目录不为空
file = new File(outputDir + File.separator + subDir);
}
if(!file.exists()){
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
file.mkdirs();
}
}

/**
* 判断程序运行在什么系统上
* @return 系统类型
*/
public static String systemType() {
Properties properties = System.getProperties();
String os = properties.getProperty("os.name");
if (os != null && os.toLowerCase().contains(WINDOWS)){
return WINDOWS;
}else if (os != null && os.toLowerCase().contains(LINUX)){
return LINUX;
}
return null;
}

public static void main(String[] args) {
//deCompress("E:/Test/Test01.zip","E:/Test/testZip");
//deCompress("E:/Test/Test02.rar","E:/Test/testRar");
//deCompress("E:/Test/Test03.7z","E:/Test/test7z");
//deCompress("E:/Test/Test04.tar","E:/Test/testTar");
//deCompress("E:/Test/apache-tomcat-9.0.13-src.tar.gz","E:/Test/testTarGz");
}

从服务器下载文件

下载已经打包好的文件

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
/**
* 文件下载
* @param zipFileName zip文件全路径(含文件名)
* @param response
* @param isDelete 是否将生成的服务器端文件删除
* @return
*/
public ReturnT<?> downloadFile(String zipFileName,
HttpServletResponse response, boolean isDelete) {
try {
File file=new File(zipFileName);
// 以流的形式下载文件。
BufferedInputStream fis =
new BufferedInputStream(new FileInputStream(file.getPath()));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" +
new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"));
toClient.write(buffer);
toClient.flush();
toClient.close();
if(isDelete) {
//将生成的服务器端文件删除
file.delete();
}
return new ReturnT(HttpStatus.OK, "下载成功", null);
} catch (Exception e) {
logger.error("下载失败",e);
return new ReturnT(HttpStatus.NOT_FOUND, "下载失败", null);
}
}

变打包边下载

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
/**
* 下载-边打包边下载
* @param downloadName 压缩包的名字
* @param fileList 所有需要下载的文件列表
* @param request
* @param response
* @return
*/
@Override
public ReturnT<?> downloadFile(String downloadName, List<File> fileList,
HttpServletRequest request, HttpServletResponse response) {

//响应头的设置
response.reset();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");

//设置压缩包的名字
//解决不同浏览器压缩包名字含有中文时乱码的问题
String agent = request.getHeader("USER-AGENT");
try {
if (agent.contains("MSIE")||agent.contains("Trident")) {
downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
} else {
downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1");
}
} catch (Exception e) {
e.printStackTrace();
return new ReturnT(HttpStatus.NOT_FOUND, "下载失败", null);
}
response.setHeader("Content-Disposition", "attachment;fileName=\""
+ downloadName + "\"");

//设置压缩流:直接写入response,实现边压缩边下载
ZipOutputStream zipos = null;
try {
zipos = new ZipOutputStream(
new BufferedOutputStream(response.getOutputStream()));
zipos.setMethod(ZipOutputStream.DEFLATED); //设置压缩方法
} catch (Exception e) {
e.printStackTrace();
return new ReturnT(HttpStatus.NOT_FOUND, "下载失败", null);
}

//循环将文件写入压缩流
DataOutputStream os = null;
for(int i = 0; i < fileList.size(); i++ ){
File file = fileList.get(i);
try {
//添加ZipEntry,并ZipEntry中写入文件流
//这里,加上i是防止要下载的文件有重名的导致下载失败
zipos.putNextEntry(new ZipEntry(i + file.getName()));
os = new DataOutputStream(zipos);
InputStream is = new FileInputStream(file);
byte[] b = new byte[100];
int length = 0;
while((length = is.read(b))!= -1){
os.write(b, 0, length);
}
is.close();
zipos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
return new ReturnT(HttpStatus.NOT_FOUND, "下载失败", null);
}
}

//关闭流
try {
os.flush();
os.close();
zipos.close();
} catch (IOException e) {
e.printStackTrace();
return new ReturnT(HttpStatus.NOT_FOUND, "下载失败", null);
}

return new ReturnT(HttpStatus.OK, "下载成功", null);
}

其它文件操作

获取单个文件的所有内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 获取单个文件的所有内容
* @param fileName 文件全路径
* @return
*/
public static String readToString(String fileName) {
try {
File file = new File(fileName);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
return new String(filecontent, encoding);
} catch (FileNotFoundException e) {
logger.error("该文件不存在或路径错误",e);
e.printStackTrace();
return null;
} catch (IOException e) {
logger.error("读取文件出错",e);
e.printStackTrace();
return null;
}
}

获取多个文件的文件名列表(全路径)

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
/**
* 获取多个文件文件列表(全路径)
* @param fileDir 文件夹路径
* @param picturePath 图片相对路径
* @param request
* @return 返回带域名的文件路径
*/
public static List<String> readToListPath(String fileDir, String picturePath, HttpServletRequest request) {
//获取带部署环境上下文的域名
StringBuffer url = request.getRequestURL();
String tempContextUrl = url
.delete(url.length() - request.getRequestURI().length(), url.length())
.append(request.getContextPath()).toString();

List<String> fileNameList = new ArrayList<>();
try {
List<File> fileList = getFilePath(fileDir,"");
if (fileList.size()==0){
return fileNameList;
}
for (File f1 : fileList) {
fileNameList.add(tempContextUrl+picturePath+"/"+f1.getName());
}
return fileNameList;
}catch (Exception e){
logger.error("获取多个文件文件列表异常",e);
e.printStackTrace();
return null;
}
}

获取多个文件的内容列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 获取多个文件内容列表
* @param fileDir 文件所在路径
* @return
*/
public static List<String> readToListAndString(String fileDir){
try {
List<String> fileContentList = new ArrayList<>();
List<File> fileList = getFilePath(fileDir,"");
for (File file : fileList){
if(!readToString(file.toString()).equals("")){
fileContentList.add(readToString(file.toString()));
}
}
return fileContentList;
}catch (Exception e){
logger.error("获取多个文件内容列表异常",e);
e.printStackTrace();
return null;
}
}

递归获取目录下的所有文件

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
/**
* 递归获取目录下的所有文件
* @param fileDir 文件所在路径
* @return
*/
public static List<File> getFilePath(String fileDir,String endsWith){
List<File> fileList = new ArrayList<>();
File file = new File(fileDir);
File[] files = file.listFiles();// 获取目录下的所有文件或文件夹
if (files == null) {// 如果目录为空,返回空
return null;
}
// 遍历,目录下的所有文件
for (File f : files) {
if (f.isFile()) {
if(endsWith.equals("")||endsWith==null){
fileList.add(f);
}else {
if (f.getName().endsWith(endsWith)){
fileList.add(f);
}
}

} else if (f.isDirectory()) {
getFilePath(f.getAbsolutePath(),endsWith);
}
}

return fileList;
}

递归删除文件(删除文件夹)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 递归删除目录下的所有文件及子目录下所有文件
* @param dir 目录路径
* @return
*/
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
//递归删除目录中的子目录下
for (int i=0; i<children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// 目录此时为空或者是文件,可以删除
return dir.delete();
}