【转】Java实现将文件或者文件夹压缩成zip
程序员文章站
2022-06-12 18:28:29
转自:https://www.cnblogs.com/zeng1994/p/7862288.html 注意点: ......
转自:
1 package com.guo.utils; 2 3 import java.io.*; 4 import java.util.arraylist; 5 import java.util.list; 6 import java.util.zip.zipentry; 7 import java.util.zip.zipoutputstream; 8 9 public class ziputils { 10 private static final int buffer_size = 2 * 1024; 11 12 /** 13 * 压缩成zip 方法 * @param srcdir 压缩文件夹路径 14 * @param out 压缩文件输出流 15 * @param keepdirstructure 是否保留原来的目录结构,true:保留目录结构; 16 * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) 17 * @throws runtimeexception 压缩失败会抛出运行时异常 18 */ 19 public static void tozip(string srcdir, outputstream out, boolean keepdirstructure) 20 throws runtimeexception{ 21 22 long start = system.currenttimemillis(); 23 zipoutputstream zos = null ; 24 try { 25 zos = new zipoutputstream(out); 26 file sourcefile = new file(srcdir); 27 compress(sourcefile,zos,sourcefile.getname(),keepdirstructure); 28 long end = system.currenttimemillis(); 29 system.out.println("压缩完成,耗时:" + (end - start) +" ms"); 30 } catch (exception e) { 31 throw new runtimeexception("zip error from ziputils",e); 32 }finally{ 33 if(zos != null){ 34 try { 35 zos.close(); 36 } catch (ioexception e) { 37 e.printstacktrace(); 38 } 39 } 40 } 41 42 } 43 44 /** 45 * 压缩成zip 方法 * @param srcfiles 需要压缩的文件列表 46 * @param out 压缩文件输出流 47 * @throws runtimeexception 压缩失败会抛出运行时异常 48 */ 49 public static void tozip(list<file> srcfiles , outputstream out)throws runtimeexception { 50 long start = system.currenttimemillis(); 51 zipoutputstream zos = null ; 52 try { 53 zos = new zipoutputstream(out); 54 for (file srcfile : srcfiles) { 55 byte[] buf = new byte[buffer_size]; 56 zos.putnextentry(new zipentry(srcfile.getname())); 57 int len; 58 fileinputstream in = new fileinputstream(srcfile); 59 while ((len = in.read(buf)) != -1){ 60 zos.write(buf, 0, len); 61 } 62 zos.closeentry(); 63 in.close(); 64 } 65 long end = system.currenttimemillis(); 66 system.out.println("压缩完成,耗时:" + (end - start) +" ms"); 67 } catch (exception e) { 68 throw new runtimeexception("zip error from ziputils",e); 69 }finally{ 70 if(zos != null){ 71 try { 72 zos.close(); 73 } catch (ioexception e) { 74 e.printstacktrace(); 75 } 76 } 77 } 78 } 79 80 81 /** 82 * 递归压缩方法 83 * @param sourcefile 源文件 84 * @param zos zip输出流 85 * @param name 压缩后的名称 86 * @param keepdirstructure 是否保留原来的目录结构,true:保留目录结构; 87 * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) 88 * @throws exception 89 */ 90 private static void compress(file sourcefile, zipoutputstream zos, string name, 91 boolean keepdirstructure) throws exception{ 92 byte[] buf = new byte[buffer_size]; 93 if(sourcefile.isfile()){ 94 // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字 95 zos.putnextentry(new zipentry(name)); 96 // copy文件到zip输出流中 97 int len; 98 fileinputstream in = new fileinputstream(sourcefile); 99 while ((len = in.read(buf)) != -1){ 100 zos.write(buf, 0, len); 101 } 102 // complete the entry 103 zos.closeentry(); 104 in.close(); 105 } else { 106 //是文件夹 107 file[] listfiles = sourcefile.listfiles(); 108 if(listfiles == null || listfiles.length == 0){ 109 // 需要保留原来的文件结构时,需要对空文件夹进行处理 110 if(keepdirstructure){ 111 // 空文件夹的处理 112 zos.putnextentry(new zipentry(name + "/")); 113 // 没有文件,不需要文件的copy 114 zos.closeentry(); 115 } 116 117 }else { 118 for (file file : listfiles) { 119 // 判断是否需要保留原来的文件结构 120 if (keepdirstructure) { 121 // 注意:file.getname()前面需要带上父文件夹的名字加一斜杠, 122 // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了 123 compress(file, zos, name + "/" + file.getname(),keepdirstructure); 124 } else { 125 compress(file, zos, file.getname(),keepdirstructure); 126 } 127 128 } 129 } 130 } 131 } 132 133 public static void main(string[] args) throws exception { 134 /** 测试压缩方法 */ 135 fileoutputstream fos1= new fileoutputstream(new file("e:/testzip.zip")); 136 ziputils.tozip("e:/testzip", fos1,true); 137 138 /** 测试压缩方法 */ 139 list<file> filelist = new arraylist<>(); 140 filelist.add(new file("d:/java/jdk1.7.0_45_64bit/bin/jar.exe")); 141 filelist.add(new file("d:/java/jdk1.7.0_45_64bit/bin/java.exe")); 142 fileoutputstream fos2= new fileoutputstream(new file("c:/mytest02.zip")); 143 ziputils.tozip(filelist, fos2); 144 } 145 }
注意点:
- 文件和文件夹的压缩,通过递归的compress方法来实现,从最深的一层开始。
- 如果是文件夹,在传name时,需要在前面带一个“/”。表示是文件夹。
第123行:compress(file, zos, name + "/" + file.getname(),keepdirstructure);
- 空文件夹要保留,也是通过后面加“/”。
- 压缩包中的文件,通过zipentry对象来添加,添加完之后,需要通过流的closeentry()来关闭。
- web项目中,把response写到返回流中就行。
上一篇: Asp.net 文本框全选的实现
下一篇: 如何提高河南特种水产养殖效益呢?