java壓縮與解壓縮

jopen 11年前發布 | 12K 次閱讀 Java開發 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())) {
       return getRelativePath(basePath, file.getParentFile())+File.separator+file.getName();
      
      } else {
       return file.getName();
      
      } }

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!