java ant包中的org.apache.tools.zip实现压缩和解压缩实例详解
程序员文章站
2024-03-01 13:03:40
java ant包中的org.apache.tools.zip实现压缩和解压缩实例详解
其实apache中的ant包(请自行google之ant.jar)中有一个更好的类...
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, '/'); 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('\\', '/'); // 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('\\', '/').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:\\中文")); } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
上一篇: springMVC发送邮件的简单实现
下一篇: Python的语言类型(详解)