我們在工作中遇到文件的壓縮的解壓,我在使用的時候有遇到中文的時候,就會造成亂碼。這個也是經常會用到工具類,所以就把工具類貼出來供大家參考。
1、引入依賴,這個依賴能夠制定壓縮文件名的編碼。
<!-- ant.jar 用於解決文件解壓縮亂碼問題 -->
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
2、工具類,這裏涉及tools類和java自帶的類可能不容易分清,在這裏也將依賴引入。這裏如過沒有編碼問題需要將編碼更改爲 gbk。
package com.yin.databaseproject.util;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* @author yin
* @Date 2020/1/12 14:51
* @Method
*/
public class ZipUtils {
private static Integer BUFFER_SIZE = 4 * 1024;
public static synchronized boolean unZip(String zipFileName, String extPlace,String encode) {
try {
return unZipFiles(zipFileName, extPlace,encode);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 解壓zip格式文件到指定位置
* @param zipFileName
* @param extPlace
* @return
*/
private static boolean unZipFiles(String zipFileName, String extPlace,String encode) {
try {
(new File(extPlace)).mkdirs();
File file = new File(zipFileName);
ZipFile zipFile = new ZipFile(zipFileName,encode);
if ((!file.exists()) && (file.length() <= 0)) {
throw new Exception("要解壓文件不存在");
}
String strPath,gbkPath,strtemp;
File tempFile = new File(extPlace);
strPath = tempFile.getAbsolutePath();
Enumeration<ZipEntry> e = zipFile.getEntries();
while (e.hasMoreElements()) {
ZipEntry zipEnt = e.nextElement();
gbkPath = zipEnt.getName();
if (zipEnt.isDirectory()) {
strtemp = strPath + File.separator + gbkPath;
File dir = new File(strtemp);
dir.mkdirs();
continue;
}else {
//讀寫文件
InputStream is = zipFile.getInputStream(zipEnt);
BufferedInputStream bis = new BufferedInputStream(is);
gbkPath = zipEnt.getName();
strtemp= strPath + File.separator + gbkPath;
//建目錄
String strsubdir = gbkPath;
for (int i = 0; i < strsubdir.length(); i++) {
if (strsubdir.substring(i, i + 1).endsWith("/")) {
String temp = strPath + File.separator + strsubdir.substring(0, i);
File subdir = new File(temp);
if (!subdir.exists()) {
subdir.mkdir();
}
}
}
FileOutputStream fos = new FileOutputStream(strtemp);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int c;
while ((c = bis.read()) != -1) {
bos.write((byte) c);
}
bos.close();
fos.close();
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
*
* 壓縮成zip 方法1
*
* @param srcDir 壓縮文件的路徑
* @param out 壓縮文件輸出流
* @param keepDirStructure 是否保持原來的目錄結構,true :保留目錄結構
* false :所有文件會跑到壓縮包根目錄下(如果出現相同包名會出現壓縮失敗)
*/
public static void toZip(String srcDir, OutputStream out, boolean keepDirStructure,String encode) {
long start = System.currentTimeMillis();
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
zos.setEncoding(encode);
File sourceFile = new File(srcDir);
compress(sourceFile, zos, sourceFile.getName(), keepDirStructure);
long end = System.currentTimeMillis();
System.out.println("壓縮完成,耗時:" + (end - start) + "ms");
} catch (Exception e) {
throw new RuntimeException("zip error fail", e);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void toZip(List<File> srcFiles, OutputStream out,String encode) throws RuntimeException{
long start = System.currentTimeMillis();
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
// 設置壓縮的編碼,解決壓縮路徑中的中文亂碼問題
zos.setEncoding(encode);
for (File srcFile : srcFiles) {
byte[] buf = new byte[BUFFER_SIZE];
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int len;
FileInputStream in = new FileInputStream(srcFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
long end= System.currentTimeMillis();
System.out.println("完成壓縮,耗時" +(end - start) + "ms");
} catch (Exception e) {
throw new RuntimeException("zip error fail", e);
}finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void compress(File sourceFile, ZipOutputStream zos,
String name, boolean keepDirStructure) throws Exception {
byte[] buf = new byte[BUFFER_SIZE];
if(sourceFile.isFile()){
//向zip輸出流中添加一個zip實體,構造器中name爲實體的文件的名字
zos.putNextEntry(new ZipEntry(name));
//copy文件到zip輸出流
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}else {
File[] listFiles = sourceFile.listFiles();
if (listFiles == null || listFiles.length == 0) {
//需要保留原來文件結構,需要對空文件夾進行處理
if (keepDirStructure) {
//空文件夾的處理
zos.putNextEntry(new ZipEntry(name + "/"));
//沒有文件,不需要copy
zos.closeEntry();
}
}else{
for (File file : listFiles) {
if (keepDirStructure) {
//注意:file.getName() 前面需要帶上父文件夾的名字加一斜槓
//不然最後壓縮包中就不能保留原來文件結構,所有文件都跑到根目錄下面了
compress(file, zos, name + "/" + file.getName(), keepDirStructure);
}else {
compress(file, zos, file.getName(), keepDirStructure);
}
}
}
}
}
public static void main(String[] args) throws FileNotFoundException {
String namePath = "C:\\Users\\Administrator\\Desktop\\test.zip";
String namePath12 = "C:\\Users\\Administrator\\Desktop\\test12.zip";
List<File> list = new ArrayList<File>();
list.add(new File("C:\\Users\\Administrator\\Desktop\\經驗文檔\\aop學習.doc"));
list.add(new File("C:\\Users\\Administrator\\Desktop\\新建文本文檔 (2).txt"));
list.add(new File("C:\\Users\\Administrator\\Desktop\\asa.xls"));
FileOutputStream fos = new FileOutputStream(new File(namePath));
FileOutputStream fos12 = new FileOutputStream(new File(namePath12));
toZip(list,fos,"gbk");
toZip("C:\\Users\\Administrator\\Desktop\\經驗文檔",fos12,true,"gbk");
System.out.println("\n壓縮完成 路徑:" + namePath);
unZip(namePath,"C:\\Users\\Administrator\\Desktop\\解壓","gbk");
unZip(namePath12,"C:\\Users\\Administrator\\Desktop\\解壓12","gbk");
}
}