Java ZIP压缩和解压缩文件(解决中文文件名乱码问题)

 

JDK中自带的ZipOutputStream在压缩文件时,如果文件名中有中文,则压缩后的

zip文件打开时发现中文文件名变成乱码.

 

 

解决的方法是使用apache-ant-zip.jar包(见附件)中的ZipOutputStream和ZipEntry.

即,导入类:

 

import org.apache.tools.zip.ZipEntry; 

import org.apache.tools.zip.ZipOutputStream;

 

并且注意,压缩之前调用ZipOutputStream的out.setEncoding(System.getProperty("sun.jnu.encoding"));方法,

系统参数sun.jnu.encoding表示获取当前系统中的文件名的编码方式.这里将ZipOutputStream的文件名编码方式

设置成系统的文件名编码方式.

 

解压时,直接使用JDK原来的ZipInputStream即可.

 

但是有个需要注意的地方是,在读取ZIP文件之前,需要设置:

System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding"));

将系统的ZIP编码格式设置为系统文件名编码方式,否则解压时报异常.

(网上,还有修改ZipInputStream源码的方式貌似太麻烦了,参考:http://zwllxs.iteye.com/blog/871260)

 

ZIP代码参考http://szhnet.iteye.com/blog/199059,有修改.

package io;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

public class Zip
{
  static final int BUFFER = 8192;

  public Zip()
  {

  }

  private static void compress(File file, ZipOutputStream out, String basedir)
  {
    /* 判断是目录还是文件 */
    if (file.isDirectory())
    {
      // System.out.println("压缩:" + basedir + file.getName());
      compressDirectory(file, out, basedir);
    }
    else
    {
      // System.out.println("压缩:" + basedir + file.getName());
      compressFile(file, out, basedir);
    }
  }

  /** 压缩一个目录 */
  private static void compressDirectory(File dir, ZipOutputStream out, String basedir)
  {
    if (!dir.exists()) return;

    File[] files = dir.listFiles();
    for (int i = 0; i < files.length; i++)
    {
      /* 递归 */
      compress(files[i], out, basedir + dir.getName() + "/");
    }
  }

  /** 压缩一个文件 */
  private static void compressFile(File file, ZipOutputStream out, String basedir)
  {
    if (!file.exists())
    {
      return;
    }
    try
    {
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
      ZipEntry entry = new ZipEntry(basedir + file.getName());
      out.putNextEntry(entry);
      int count;
      byte data[] = new byte[BUFFER];
      while ((count = bis.read(data, 0, BUFFER)) != -1)
      {
        out.write(data, 0, count);
      }
      bis.close();
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
  }

  public static void zip(String srcPathName, String zipFileName)
  {
    File file = new File(srcPathName);
    File zipFile = new File(zipFileName);
    if (!file.exists()) throw new RuntimeException(srcPathName + "不存在!");
    try
    {
      FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
      CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new CRC32());
      ZipOutputStream out = new ZipOutputStream(cos);
      out.setEncoding(System.getProperty("sun.jnu.encoding"));//设置文件名编码方式
      String basedir = "";
      compress(file, out, basedir);
      out.close();
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
  }

  public static void main(String[] args)
  {
    Zip.zip("D:\\D\\dll", "D:\\D\\dll.zip");
  }
}

 

UnZip代码:

package io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


public class UnZip
{

  public static void unzip(String zipFilePath, String destDir)
  {
    System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding")); //防止文件名中有中文时出错
    //System.out.println(System.getProperty("sun.zip.encoding")); //ZIP编码方式
    //System.out.println(System.getProperty("sun.jnu.encoding")); //当前文件编码方式
    //System.out.println(System.getProperty("file.encoding")); //这个是当前文件内容编码方式
    
    File dir = new File(destDir);
    // create output directory if it doesn't exist
    if (!dir.exists()) dir.mkdirs();
    FileInputStream fis;
    // buffer for read and write data to file
    byte[] buffer = new byte[1024];
    try
    {
      fis = new FileInputStream(zipFilePath);
      ZipInputStream zis = new ZipInputStream(fis);
      ZipEntry ze = zis.getNextEntry();
      while (ze != null)
      {
        String fileName = ze.getName();
        File newFile = new File(destDir + File.separator + fileName);
        //System.out.println("Unzipping to " + newFile.getAbsolutePath());
        // create directories for sub directories in zip
        new File(newFile.getParent()).mkdirs();
        FileOutputStream fos = new FileOutputStream(newFile);
        int len;
        while ((len = zis.read(buffer)) > 0)
        {
          fos.write(buffer, 0, len);
        }
        fos.close();
        // close this ZipEntry
        zis.closeEntry();
        ze = zis.getNextEntry();
      }
      // close last ZipEntry
      zis.closeEntry();
      zis.close();
      fis.close();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }

  }

  public static void main(String[] args)
  {
    String zipFilePath = "D:\\D\\dll.zip";

    String destDir = "D:\\D\\dll_zip";

    UnZip.unzip(zipFilePath, destDir);
  }

}

 

 

你可能感兴趣的:(java,压缩,zip,解压缩)