搜索
首页Javajava教程java ant包中实现压缩和解压缩实例详解

这篇文章主要介绍了java ant包中的org.apache.tools.zip实现压缩和解压缩实例详解的相关资料,需要的朋友可以参考下

java ant包中的org.apache.tools.zip实现压缩和解压缩实例详解

其实apache中的ant包(请自行GOOGLE之ant.jar)中有一个更好的类,已经支持中文了,我们就不重复制造轮子了,拿来用吧,
这里最主要的功能是实现了 可以指定多个文件 到同一个压缩包的功能

用org.apache.tools.zip压缩/解压缩zip文件的例子,用来解决中文乱码问题。

实例代码:

import Java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.Deflater;

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

/**
 * 功能:使用Apache Ant里提供的org.apache.tools.zip实现zip压缩和解压 (支持中文文件名)
 * 解决了由于java.util.zip包不支持汉字的问题。 使用java.util.zip包时,当zip文件中有名字为中文的文件时,
 * 就会出现异常:"Exception in thread "main " java.lang.IllegalArgumentException at
 * java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285)
 * 
 * @author 夏明龙 E-mail:邮箱
 * @version 创建时间:2013-3-22 上午10:40:21 类说明:
 */
public class AntZipUtil {
 private static List list = new ArrayList();

 private static List listFile(String path) {
 File file = new File(path);
 String[] array = null;
 String sTemp = "";

 if (!file.isDirectory()) {
  return null;
 }
 array = file.list();
 if (array.length > 0) {
  for (int i = 0; i < array.length; i++) {
  sTemp = path + array[i];
  file = new File(sTemp);
  if (file.isDirectory()) {
   listFile(sTemp + "/");
  } else
   list.add(sTemp);
  }
 } else {
  return null;
 }

 return list;
 }

 public static void zip(String needtozipfilepath, String zipfilepath){
 try {
  byte[] b = new byte[512];

  File needtozipfile = new File(needtozipfilepath);

  if (!needtozipfile.exists()) {
  System.err.println("指定的要压缩的文件或目录不存在.");
  return;
  }

  String zipFile = zipfilepath;
  File targetFile = new File(zipFile.substring(0, zipFile.indexOf("\\") + 1));

  if (!targetFile.exists()) {
  System.out.println("指定的目标文件或目录不存在.");
  return;
  }

  String filepath = needtozipfilepath;
  List fileList = listFile(filepath);
  FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
  CheckedOutputStream cs = new CheckedOutputStream(fileOutputStream,new CRC32());
  ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(cs));

  for (int i = 0; i < fileList.size(); i++) {
  InputStream in = new FileInputStream((String) fileList.get(i));
  String fileName = ((String) fileList.get(i)).replace(File.separatorChar, &#39;/&#39;);
  fileName = fileName.substring(fileName.indexOf("/") + 1);
  ZipEntry e = new ZipEntry(fileName);
  out.putNextEntry(e);
  int len = 0;
  while ((len = in.read(b)) != -1) {
   out.write(b, 0, len);
  }
  out.closeEntry();
  }
  out.close();
 } catch (Exception e) {
  e.printStackTrace();
 }
 }

 // ///////////////////////////////////////
 /**
 * 压缩文件 或者 文件夹
 * 
 * @param baseDirName
 *      压缩的根目录
 * @param fileName
 *      根目录下待压缩的文件或文件夹名
 * @param targetFileName
 *      目标ZIP 文件 星号 "*" 表示压缩根目录下的全部文件
 * 
 */
 public static boolean zip(String baseDirName, String[] fileNames,
  String targetFileName, String encoding) {
 boolean flag = false;
 try {
  // 判断 "压缩的根目录"是否存在! 是否是一个文件夹!
  File baseDir = new File(baseDirName);
  if (!baseDir.exists() || (!baseDir.isDirectory())) {
  System.err.println("压缩失败! 根目录不存在: " + baseDirName);
  return false;
  }

  // 得到这个 "压缩的根目录" 的绝对路径
  String baseDirPath = baseDir.getAbsolutePath();

  // 由这个 "目标 ZIP 文件" 文件名得到一个 压缩对象 ZipOutputStream
  File targetFile = new File(targetFileName);
  ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
   targetFile));
  // 中文有乱码,引进下面的改造类
  // CnZipOutputStream out = new CnZipOutputStream(new
  // FileOutputStream(targetFile),encoding);

  // 设置压缩编码Apache Ant有个包专门处理ZIP文件,可以指定文件名的编码方式。由此可以解决问题。例如:用
  // org.apache.tools.zip.ZipOutputStream代替java.util.zip.ZipOutputStream。ZipOutputStream
  // out = .....; out.setEncoding("GBK");
  // out.setEncoding("GBK");//设置为GBK后在windows下就不会乱码了,如果要放到Linux或者Unix下就不要设置了
  out.setEncoding(encoding);

  // "*" 表示压缩包括根目录 baseDirName 在内的全部文件 到 targetFileName文件下
  if (fileNames.equals("*")) {
  AntZipUtil.dirToZip(baseDirPath, baseDir, out);
  } else {
  File[] files = new File[fileNames.length];
  for (int i = 0; i < files.length; i++) {
   // 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
   files[i] = new File(baseDir, fileNames[i]);
  }
  if (files[0].isFile()) {
   // 调用本类的一个静态方法 压缩一个文件
   // CompressUtil.fileToZip(baseDirPath, file, out);
   AntZipUtil.filesToZip(baseDirPath, files, out);
  }

  }
  out.close();
  // System.out.println("压缩成功! 目标文件名为: " + targetFileName);
  flag = true;
 } catch (FileNotFoundException e) {
  e.printStackTrace();
 } catch (IOException e) {
  e.printStackTrace();
 }
 return flag;
 }

 /**
 * 将文件压缩到Zip 输出流
 * 
 * @param baseDirPath
 *      根目录路径
 * @param file
 *      要压缩的文件
 * @param out
 *      输出流
 * @throws IOException
 */
 private static void fileToZip(String baseDirPath, File file,
  ZipOutputStream out) throws IOException {
 //
 FileInputStream in = null;
 org.apache.tools.zip.ZipEntry entry = null;
 // 创建复制缓冲区 1024*4 = 4K
 byte[] buffer = new byte[1024 * 4];
 int bytes_read = 0;
 if (file.isFile()) {
  in = new FileInputStream(file);
  // 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例
  String zipFileName = getEntryName(baseDirPath, file);
  entry = new org.apache.tools.zip.ZipEntry(zipFileName);
  // "压缩文件" 对象加入 "要压缩的文件" 对象
  out.putNextEntry(entry);
  // 现在是把 "要压缩的文件" 对象中的内容写入到 "压缩文件" 对象
  while ((bytes_read = in.read(buffer)) != -1) {
  out.write(buffer, 0, bytes_read);
  }
  out.closeEntry();
  in.close();
  // System.out.println("添加文件" + file.getAbsolutePath()+ "被添加到 ZIP
  // 文件中!");
 }
 }

 /**
 * 多个文件目录压缩到Zip 输出流
 * 
 * @param baseDirPath
 * @param files
 * @param out
 * @throws IOException
 */
 @SuppressWarnings("unused")
 private static void filesToZip(String baseDirPath, File[] files,
  ZipOutputStream out) throws IOException {
 // 遍历所有的文件 一个一个地压缩
 for (int i = 0; i < files.length; i++) {
  File file = files[i];
  if (file.isFile()) {
  // 调用本类的一个静态方法 压缩一个文件
  AntZipUtil.fileToZip(baseDirPath, file, out);
  } else {
  /*
   * 这是一个文件夹 所以要再次得到它下面的所有的文件 这里是自己调用自己..............递归..........
   */
  AntZipUtil.dirToZip(baseDirPath, file, out);
  }
 }
 }

 /**
 * 将文件目录压缩到Zip 输出流
 * 
 * @param baseDirPath
 * @param dir
 * @param out
 * @throws IOException
 */
 private static void dirToZip(String baseDirPath, File dir,
  ZipOutputStream out) throws IOException {
 // 得到一个文件列表 (本目录下的所有文件对象集合)
 File[] files = dir.listFiles();
 // 要是这个文件集合数组的长度为 0 , 也就证明了这是一个空的文件夹,虽然没有再循环遍历它的必要,但是也要把这个空文件夹也压缩到目标文件中去
 if (files.length == 0) {
  // 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例
  String zipFileName = getEntryName(baseDirPath, dir);
  org.apache.tools.zip.ZipEntry entry = new org.apache.tools.zip.ZipEntry(
   zipFileName);
  out.putNextEntry(entry);
  out.closeEntry();
 } else {
  // 遍历所有的文件 一个一个地压缩
  for (int i = 0; i < files.length; i++) {
  File file = files[i];
  if (file.isFile()) {
   // 调用本类的一个静态方法 压缩一个文件
   AntZipUtil.fileToZip(baseDirPath, file, out);
  } else {
   /*
   * 这是一个文件夹 所以要再次得到它下面的所有的文件
   * 这里是自己调用自己..............递归..........
   */
   AntZipUtil.dirToZip(baseDirPath, file, out);
  }
  }
 }
 }

 /**
 * 获取 待压缩文件在 ZIP 文件中的 entry的名字,即相对于根目录的相对路径名
 * 
 * @param baseDirPath
 *      根目录
 * @param file
 * @return
 */
 private static String getEntryName(String baseDirPath, File file) {
 /**
  * 改变 baseDirPath 的形式 把 "C:/temp" 变成 "C:/temp/"
  */
 if (!baseDirPath.endsWith(File.separator)) {
  baseDirPath += File.separator;
 }
 String filePath = file.getAbsolutePath();
 /**
  * 测试此抽象路径名表示的文件是否是一个目录。 要是这个文件对象是一个目录 则也要变成 后面带 "/" 这个文件对象类似于
  * "C:/temp/人体写真/1.jpg" 要是这个文件是一个文件夹 则也要变成 后面带 "/"
  * 因为你要是不这样做,它也会被压缩到目标文件中 但是却不能正解显示 也就是说操作系统不能正确识别它的文件类型(是文件还是文件夹)
  */
 if (file.isDirectory()) {
  filePath += "/";
 }
 int index = filePath.indexOf(baseDirPath);
 return filePath.substring(index + baseDirPath.length());
 }

 // //////////////////////////解压缩////////////////////////////////////////
 /**
 * 调用org.apache.tools.zip实现解压缩,支持目录嵌套和中文名
 * 也可以使用java.util.zip不过如果是中文的话,解压缩的时候文件名字会是乱码。原因是解压缩软件的编码格式跟java.util.zip.ZipInputStream的编码字符集(固定是UTF-8)不同
 * 
 * @param zipFileName
 *      要解压缩的文件
 * @param outputDirectory
 *      要解压到的目录
 * @throws Exception
 */
 public static boolean unZip(String zipFileName, String outputDirectory) {
 boolean flag = false;
 try {
  org.apache.tools.zip.ZipFile zipFile = new org.apache.tools.zip.ZipFile(
   zipFileName);
  java.util.Enumeration e = zipFile.getEntries();
  org.apache.tools.zip.ZipEntry zipEntry = null;
  createDirectory(outputDirectory, "");
  while (e.hasMoreElements()) {
  zipEntry = (org.apache.tools.zip.ZipEntry) e.nextElement();
  // System.out.println("unziping " + zipEntry.getName());
  if (zipEntry.isDirectory()) {
   String name = zipEntry.getName();
   name = name.substring(0, name.length() - 1);
   File f = new File(outputDirectory + File.separator + name);
   f.mkdir();
   System.out.println("创建目录:" + outputDirectory
    + File.separator + name);
  } else {
   String fileName = zipEntry.getName();
   fileName = fileName.replace(&#39;\\&#39;, &#39;/&#39;);
   // System.out.println("测试文件1:" +fileName);
   if (fileName.indexOf("/") != -1) {
   createDirectory(outputDirectory, fileName.substring(0,
    fileName.lastIndexOf("/")));
   fileName = fileName.substring(
    fileName.lastIndexOf("/") + 1, fileName
     .length());
   }

   File f = new File(outputDirectory + File.separator
    + zipEntry.getName());

   f.createNewFile();
   InputStream in = zipFile.getInputStream(zipEntry);
   FileOutputStream out = new FileOutputStream(f);

   byte[] by = new byte[1024];
   int c;
   while ((c = in.read(by)) != -1) {
   out.write(by, 0, c);
   }
   out.close();
   in.close();
  }
  flag = true;
  }
 } catch (Exception ex) {
  ex.printStackTrace();
 }
 return flag;
 }

 /**
 * 创建目录
 * 
 * @param directory
 *      父目录
 * @param subDirectory
 *      子目录
 */
 private static void createDirectory(String directory, String subDirectory) {
 String dir[];
 File fl = new File(directory);
 try {
  if (subDirectory == "" && fl.exists() != true)
  fl.mkdir();
  else if (subDirectory != "") {
  dir = subDirectory.replace(&#39;\\&#39;, &#39;/&#39;).split("/");
  for (int i = 0; i < dir.length; i++) {
   File subFile = new File(directory + File.separator + dir[i]);
   if (subFile.exists() == false)
   subFile.mkdir();
   directory += File.separator + dir[i];
  }
  }
 } catch (Exception ex) {
  System.out.println(ex.getMessage());
 }
 }

 // /////////////////////////////////////

 public static void main(String[] temp) {
 // 压缩
 String baseDirName = "C:\\";
 String[] fileNames = { "中文1.doc", "中文2.doc" };
 String zipFileName = "c:\\中文.zip";
 // 压缩多个指定的文件 到ZIP
  System.out.println(AntZipUtil.zip(baseDirName, fileNames,zipFileName,"GBK"));

 //压缩一个文件夹 到ZIP
 String sourcePath = "c:\\test\\";
 String zipFilePath = "c:\\中文2.zip";
 AntZipUtil.zip(sourcePath, zipFilePath);

 //解压缩
 //System.out.println(AntZipUtil.unZip("c:\\中文.zip", "c:\\中文"));
 }

}

【相关推荐】

1. Java免费视频教程

2. 全面解析Java注解

3. 阿里巴巴Java开发手册

以上是java ant包中实现压缩和解压缩实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?Mar 17, 2025 pm 05:46 PM

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?Mar 17, 2025 pm 05:44 PM

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?Mar 17, 2025 pm 05:43 PM

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Mar 17, 2025 pm 05:35 PM

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

如何将Java的RMI(远程方法调用)用于分布式计算?如何将Java的RMI(远程方法调用)用于分布式计算?Mar 11, 2025 pm 05:53 PM

本文解释了用于构建分布式应用程序的Java的远程方法调用(RMI)。 它详细介绍了接口定义,实现,注册表设置和客户端调用,以解决网络问题和安全性等挑战。

如何使用Java的插座API进行网络通信?如何使用Java的插座API进行网络通信?Mar 11, 2025 pm 05:53 PM

本文详细介绍了用于网络通信的Java的套接字API,涵盖了客户服务器设置,数据处理和关键考虑因素,例如资源管理,错误处理和安全性。 它还探索了性能优化技术,我

如何在Java中创建自定义网络协议?如何在Java中创建自定义网络协议?Mar 11, 2025 pm 05:52 PM

本文详细介绍了创建自定义Java网络协议。 它涵盖协议定义(数据结构,框架,错误处理,版本控制),实现(使用插座),数据序列化和最佳实践(效率,安全性,维护

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),