2008年12月9日星期二

使用org.apache.tools.zip解决juva.util.Zip中不支持中文文件名操作的问题

jdk中的juva.util.Zip包处理有中文文件名的文件会出现问题,解压缩的时候就报异常,压缩后的文件用winzip打开就是乱码。原因是ZipOutputStream压缩和解压ZIP文件对文件名都是以UTF-8编码方式来处理的,而我们用winzip压缩文件对文件名只会以ASCII编码方式来处理.所以会出现编码不一致的问题。目前直到jdk6也没有解决这一问题,为解决非UTF-8文件名的问题,Apache Ant项目专门设计了替代java.util.Zip包的类。
  1. 解压缩含中文文件名的zip文件。
    import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipFile;
    import java.io.InputStream;
    import java.util.Enumeration;
    ... ...
    private void extractSourceZipFile(ZipFile zipFile, File baseDir) throws IOException {
            ZipEntry zipEntry = null;
            Enumeration e = zipFile.getEntries();
            while (e.hasMoreElements()) {
                zipEntry = (ZipEntry) e.nextElement();
                if (zipEntry.isDirectory()) {
                    new File(baseDir + File.separator + zipEntry.getName()).mkdirs();
                } else {
                    new File(baseDir + File.separator + zipEntry.getName()).getParentFile().mkdirs();
                    log.info(baseDir + File.separator + zipEntry.getName());
                    FileOutputStream fos = new FileOutputStream(baseDir + File.separator + zipEntry.getName());
                    InputStream in = zipFile.getInputStream(zipEntry);
                    IOUtils.copy(in, fos);
                    in.close();
                    fos.close();
                }
            }
        }

  2. 压缩含中文文件名文件的目录
    import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipOutputStream;
    ... ...
    private void exportZipHelper(File fs, ZipOutputStream zos, String zePath) throws IOException {
            File[] files = fs.listFiles();
           
            for (int i=0; i<files.length; i++) {
                if (files[i].isDirectory()) {
                    ZipEntry ze = new ZipEntry(zePath+"/"+files[i].getName()+"/");
                    zos.putNextEntry(ze);
                    zos.closeEntry();
                    exportZipHelper(files[i], zos, zePath+"/"+files[i].getName());
                } else {
                    FileInputStream fis = new FileInputStream(files[i]);
                    ZipEntry ze = new ZipEntry(zePath+"/"+files[i].getName());
                    zos.putNextEntry(ze);
                    IOUtils.copy(fis, zos);
                    zos.closeEntry();
                    fis.close();
                }
            }
       }

    public void exportZip(FIle fs, String zePath){
            ByteArrayOutputStream bais = new ByteArrayOutputStream();
            ZipOutputStream zos = new ZipOutputStream(bais);
               
            // Prevents java.util.zip.ZipException: ZIP file must have at least one entry
            ZipEntry ze = new ZipEntry(zePath+"/");
            zos.putNextEntry(ze);
            zos.closeEntry();
            exportZipHelper(fs, zos, zePath);
            zos.close();
    }

没有评论: