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

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);
  }

}
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
出现乱码的原因通常是因为文件编码格式与解压缩程序的编码格式不一致,或者是文件本身存在编码问题。可能的解决方法如下: 1. 检查文件编码格式是否正确。可以使用文本编辑器打开乱码文件,然后手动更改编码格式,或者使用 Python 的 `chardet` 库自动检测编码格式。 2. 使用 Python 提供的标准库 `zipfile` 进行解压缩,并在解压缩时指定编码格式。例如: ```python import zipfile with zipfile.ZipFile('example.zip', 'r') as zip_ref: for info in zip_ref.infolist(): # 检查文件名是否包含中文 if info.filename.encode('cp437').decode('gbk') != info.filename: # 解决乱码问题 filename = info.filename.encode('cp437').decode('utf-8') else: filename = info.filename zip_ref.extract(info, path='.', pwd=None, encoding='gbk') ``` 在上面的代码中,`encoding` 参数用于指定解压缩后的编码格式,这里使用了 `gbk` 编码格式。如果文件名包含中文,还需要将文件名从 `cp437` 编码格式转换为 `utf-8` 编码格式。 3. 使用第三方库 `rarfile` 进行解压缩,该库支持 Unicode 编码格式。例如: ```python import rarfile with rarfile.RarFile('example.rar') as rar_ref: for info in rar_ref.infolist(): filename = info.filename.encode('cp437').decode('utf-8') rar_ref.extract(info, path='.', pwd=None) ``` 在上面的代码中,`filename` 变量使用了与上面相同的编码转换方式,将文件名从 `cp437` 编码格式转换为 `utf-8` 编码格式。 希望这些方法能够帮助你解决压缩文件乱码问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值