主要用到apache的ant.jar,也可用jdk的相關類,但會有中文亂碼問題。最重要的倆類是ZipFile和ZipEntry,前者將zip文件轉爲java對象,後者將zip文件中的條目文件轉爲java對象。 核心代碼以下:java
壓縮代碼:apache
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);
須要注意的地方:code
針對空文件夾須要特殊處理,須要往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())) { return getRelativePath(basePath, file.getParentFile())+File.separator+file.getName(); } else { return file.getName(); } } }