java壓縮與解壓縮
主要用到apache的ant.jar,也可用jdk的相關類,但會有中文亂碼問題。最重要的倆類是ZipFile和ZipEntry,前者將zip文件轉為java對象,后者將zip文件中的條目文件轉為java對象。
核心代碼如下:
壓縮代碼:
ZipOutputStream zipOs = new ZipOutputStream(fos); ZipEntry zipEntry = new ZipEntry("entryName"); zipOs.putNextEntry(zipEntry);
解壓縮代碼:
Enumeration<ZipEntry> entries = zipFile.getEntries(); ZipEntry zipEntry = entries.nextElement(); InputStream ins = zipFile.getInputStream(zipEntry);
需要注意的地方:
針對空文件夾需要特殊處理,需要往Entry中放入”/“+文件夾名+“/“項
zipOs.putNextEntry("/");
詳細點的練習:
/**
測試文件壓縮與解壓縮 / public class TestZip {
public static void main(String[] args) {
//-->壓縮單個文件 zipSingleFileOrFolder("D:\\BIZFLOW\\src\\tst\\新建文本文檔.zip", "D:\\BIZFLOW\\src\\tst\\新建文本文檔.txt"); //-->壓縮文件夾 //zipSingleFileOrFolder("D:\\BIZFLOW\\src\\tst.zip", "D:\\BIZFLOW\\src\\tst"); //-->壓縮多個文件(不指定壓縮文件保存路徑) //zipMultiFiles("","D:\\BIZFLOW\\src\\tst\\新建文本文檔.txt","D:\\BIZFLOW\\src\\tst\\新建文本文檔 - 副本.txt"); //-->壓縮多個文件(指定壓縮文件保存路徑) //zipMultiFiles("D:\\BIZFLOW\\src\\tst\\新建.zip","D:\\BIZFLOW\\src\\tst\\新建文本文檔.txt","D:\\BIZFLOW\\src\\tst\\新建文本文檔 - 副本.txt"); //-->解壓縮文件 //unzipFile("D:\\BIZFLOW\\src\\tst\\新建", "D:\\BIZFLOW\\src\\tst\\新建文本文檔.txt等.zip");
}
/**
- 壓縮單個文件/文件夾
- @param destPath 壓縮文件保存路徑(為空串/null時默認壓縮路徑:待壓縮文件所在目錄,壓縮文件名為待壓縮文件/文件夾名+“等.zip”)
@param srcPath 待壓縮的文件路徑 */ public static void zipSingleFileOrFolder(String destPath, String srcPath) { if(StringUtils.isBlank(srcPath)) {
throw new RuntimeException("待壓縮文件夾不可為空!");
} if(StringUtils.isNotBlank(destPath) && !destPath.endsWith(".zip")) {
throw new RuntimeException("保存文件名應以.zip結尾!");
} File file = new File(srcPath); if(!file.exists()) {
throw new RuntimeException("路徑'"+srcPath+"'下未找到文件");
} if(file.isDirectory()) {
//壓縮文件夾 zipFolder(destPath, srcPath);
} else {
//壓縮單個文件 zipFile(destPath, srcPath);
} }
/**
- 壓縮多個文件
- @param destPath 壓縮文件保存路徑(為空串/null時默認壓縮路徑:待壓縮文件所在目錄,壓縮文件名為第一個待壓縮文件名+“等.zip”)
@param srcPaths 待壓縮文件路徑集合 */ public static void zipMultiFiles(String destPath, String...srcPaths) { if(srcPaths==null || srcPaths.length==0) {
throw new RuntimeException("待壓縮文件夾不可為空!");
} if(StringUtils.isNotBlank(destPath) && !destPath.endsWith(".zip")) {
throw new RuntimeException("保存文件名應以.zip結尾!");
} zipFiles(destPath, srcPaths); }
/**
- 解壓縮文件
- @param destPath 解壓縮路徑(為空串/null時默認解壓縮路徑:壓縮文件所在目錄)
@param zipPath 壓縮文件路徑 */ public static void unzipFile(String destPath, String zipPath) { if(StringUtils.isBlank(zipPath)) {
throw new RuntimeException("壓縮文件路徑不可為空!");
} if(!zipPath.endsWith(".zip")) {
throw new RuntimeException("保存文件名應以.zip結尾!");
} File file = new File(zipPath); if(StringUtils.isBlank(destPath)) {
destPath = getUnzipBasePath(file);
} if(!file.exists()) {
throw new RuntimeException("路徑'"+zipPath+"'下未找到文件");
} ZipFile zipFile; int len; byte[] buff = new byte[1024]; try {
zipFile = new ZipFile(zipPath); //獲取壓縮文件中所有條目 Enumeration<ZipEntry> entries = zipFile.getEntries(); if(entries!=null) { while(entries.hasMoreElements()) { //壓縮文件條目轉為文件或文件夾 ZipEntry zipEntry = entries.nextElement(); //獲取輸入流 InputStream ins = zipFile.getInputStream(zipEntry); BufferedInputStream bis = new BufferedInputStream(ins); File unzipFile = new File(destPath+File.separator+zipEntry.getName()); if(zipEntry.isDirectory()) { unzipFile.mkdirs(); continue; } File pf = unzipFile.getParentFile(); if(pf!=null && !pf.exists()) { pf.mkdirs(); } unzipFile.createNewFile(); FileOutputStream fos = new FileOutputStream(unzipFile); BufferedOutputStream bos = new BufferedOutputStream(fos); //輸出流寫文件 while((len=bis.read(buff, 0, 1024))!=-1) { bos.write(buff, 0, len); } bos.flush(); fos.close(); bos.close(); } }
} catch (IOException e) {
e.printStackTrace(); throw new RuntimeException();
}
}
/**
- 獲取解壓縮文件基路徑
- @param zipPath
@return */ private static String getUnzipBasePath(File zipPath) { return zipPath.getParentFile().getAbsolutePath(); }
/**
- 壓縮單個文件
- @param destPath 壓縮文件保存路徑
- @param srcPath 待壓縮文件路徑 */ private static void zipFile(String destPath, String srcPath) { zipFiles(destPath, srcPath); } /**
- 壓縮多個文件
- @param srcPath
@param zipPath */ private static void zipFiles(String destPath, String...srcPaths) { if(StringUtils.isBlank(destPath)) {
File srcFile0 = new File(srcPaths[0]); destPath = srcFile0.getParentFile().getAbsolutePath()+File.separator+srcFile0.getName()+"等.zip";
} File zipFile = new File(destPath); FileOutputStream fos = null; try {
zipFile.createNewFile(); zipFile.mkdirs(); fos = new FileOutputStream(zipFile);
} catch (IOException e) {
e.printStackTrace(); throw new RuntimeException();
} //獲取輸出流 ZipOutputStream zipOs = new ZipOutputStream(fos); //循環將多個文件轉為壓縮文件條目 for(String srcPath : srcPaths) {
if(StringUtils.isBlank(srcPath)) { throw new RuntimeException("待壓縮文件路徑不可為空!"); } File srcFile = new File(srcPath); try { ZipEntry zipEntry = new ZipEntry(srcFile.getName()); zipOs.putNextEntry(zipEntry); //獲取輸入流 FileInputStream fis = new FileInputStream(srcFile); int len; byte[] buff = new byte[1024]; //輸入/輸出流對拷 while((len=fis.read(buff))!=-1) { zipOs.write(buff, 0, len); } fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(); }
} try {
zipOs.flush(); zipOs.close();
} catch (IOException e) {
e.printStackTrace(); throw new RuntimeException();
} }
/**
- 壓縮文件夾
- @param destPath 壓縮文件保存路徑
@param srcPath 待壓縮文件夾路徑 */ private static void zipFolder(String destPath, String srcPath) { File srcFile = new File(srcPath); //如壓縮文件保存路徑為空,則默認保存路徑 if(StringUtils.isBlank(destPath)) {
destPath = srcFile.getParent()+File.separator+srcFile.getName()+".zip";
} FileOutputStream fos = null; ZipOutputStream zipOs = null; try {
fos = new FileOutputStream(destPath); zipOs = new ZipOutputStream(fos); //遞歸往壓縮文件中添加文件夾條目 zipFolder(srcFile, srcFile, zipOs); zipOs.close();
} catch (FileNotFoundException e) {
e.printStackTrace(); throw new RuntimeException();
} catch (IOException e) {
e.printStackTrace(); throw new RuntimeException();
} }
/**
- 遞歸往壓縮文件中添加文件夾條目
- @param srcFile 待壓縮文件夾路徑
- @param baseFile
@param zipOs */ private static void zipFolder(File srcFile, File baseFile, ZipOutputStream zipOs) { int len; byte[] buff = new byte[1024]; if(srcFile.isDirectory()) {
//針對空文件夾需要特殊處理,需要往Entry中放入"/"+文件夾名+"/"項 try { zipOs.putNextEntry(new ZipEntry(srcFile.getAbsolutePath().replaceFirst(baseFile.getParentFile().getAbsolutePath().replaceAll("\\\\", "\\\\\\\\"), "")+"/")); zipOs.closeEntry(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(); } //獲取當前文件夾下文件列表 File[] fileLists = srcFile.listFiles(); if(fileLists!=null && fileLists.length>0) { for (int i = 0; i < fileLists.length; i++) { //遞歸往壓縮文件中添加文件夾條目 zipFolder(fileLists[i], baseFile, zipOs); } }
} else {
//文件處理比較簡單,直接放入Entry try { FileInputStream fis = new FileInputStream(srcFile); zipOs.putNextEntry(new ZipEntry(getRelativePath(baseFile.getAbsolutePath(), srcFile))); while((len=fis.read(buff))!=-1) { zipOs.write(buff, 0, len); } zipOs.closeEntry(); fis.close(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(); }
} }
/**
- 獲取相對基路徑的相對路徑
- @param basePath
- @param file
- @return
*/
private static String getRelativePath(String basePath, File file) {
if(!basePath.equalsIgnoreCase(file.getAbsolutePath())) {
} else {return getRelativePath(basePath, file.getParentFile())+File.separator+file.getName();
} }return file.getName();
}</pre>