使用 Apache commons-compress 解压 zip 文件是件很幸福的事,可以解决 zip 包中文件名有中文时跨平台的乱码问题,不管文件是在 Windows 压缩的还是在 Mac,Linux 压缩的,解压后都没有再出现乱码问题了。
例如 Windows 下压缩 河堤.txt 为 河堤.zip,然后传给 Mac 用户,Mac 用户解压后会发现得到的文件名是乱码,因为 Windows 压缩的时候使用的是系统的编码 GB2312,而 Mac 系统默认的编码是 UTF-8,于是出现了乱码。
Gradle 依赖
1 2 3 4 5
   | dependencies {     compile 'org.apache.commons:commons-compress:1.11'     compile 'org.apache.commons:commons-lang3:3.4'     compile 'commons-io:commons-io:2.5' }
  | 
 
解压程序
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
   | import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils;
  import java.io.*; import java.util.ArrayList; import java.util.List;
  public class ExtractZip {     public static final int BUFFER_SIZE = 1024;
      
 
 
 
 
 
 
      public static List<String> unZip(File zipFile, String destDir, String encoding) throws Exception {                  if(StringUtils.isBlank(destDir)) {             destDir = zipFile.getParent();         }
          destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;         ZipArchiveInputStream is = null;         List<String> fileNames = new ArrayList<String>();
          try {             is = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(zipFile), BUFFER_SIZE), encoding);             ZipArchiveEntry entry = null;
              while ((entry = is.getNextZipEntry()) != null) {                 fileNames.add(entry.getName());                 File file = new File(destDir, entry.getName());
                  if (entry.isDirectory()) {                     FileUtils.forceMkdir(file);                  } else {                     OutputStream os = null;
                      try {                         FileUtils.touch(file);                         os = new FileOutputStream(new File(destDir, entry.getName()));                         IOUtils.copy(is, os);                     } finally {                         IOUtils.closeQuietly(os);                     }                 }             }         } catch(Exception e) {             e.printStackTrace();             throw e;         } finally {             IOUtils.closeQuietly(is);         }
          return fileNames;     }
      
 
 
 
 
 
 
      public static List<String> unZip(String zipFile, String destDir, String encoding) throws Exception {         File zipfile = new File(zipFile);         return unZip(zipfile, destDir, encoding);     }
      public static List<String> unZip(String zipFile, String destDir) throws Exception {         return unZip(zipFile, destDir, "UTF-8");     }
      public static void main(String[] args) throws Exception {         List<String> names = unZip("/Users/Biao/Desktop/x.zip", "/Users/Biao/Desktop/x");         System.out.println(names);     } }
   | 
 
测试
例如我这测试用的压缩文件是在 Windows 压缩的,解压程序在 Mac 执行的,解压后没有乱码,输出也没有乱码:
[测试页面.files/, 测试页面.files/image001.jpg, 测试页面.htm]