感谢“zlex.dongliang@gmail.com”。主要代码如下:

  1 import java.io.BufferedInputStream;
  2 import java.io.File;
  3 import java.io.FileInputStream;
  4 import java.io.FileOutputStream;
  5 import java.io.InputStream;
  6 import java.util.Enumeration;
  7 import java.util.zip.CRC32;
  8 import java.util.zip.CheckedOutputStream;
  9 import java.util.zip.ZipEntry;
 10 import java.util.zip.ZipFile;
 11 import java.util.zip.ZipOutputStream;
 12 
 13 /**
 14  * ZIP压缩工具
 15  * 
 16  * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>
 17  * @since 1.0
 18  */
 19 public class ZipUtils {
 20 
 21     public static final String EXT = ".zip";
 22     private static final String BASE_DIR = "";
 23 
 24     // 符号"/"用来作为目录标识判断符
 25     private static final String PATH = "/";
 26     private static final int BUFFER = 1024;
 27 
 28     /**
 29      * 压缩
 30      * 
 31      * @param srcFile
 32      * @throws Exception
 33      */
 34     public static void compress(File srcFile) throws Exception {
 35         String name = srcFile.getName();
 36         String basePath = srcFile.getParent();
 37         String destPath = basePath + name + EXT;
 38         compress(srcFile, destPath);
 39     }
 40 
 41     /**
 42      * 压缩
 43      * 
 44      * @param srcFile
 45      *            源路径
 46      * @param destPath
 47      *            目标路径
 48      * @throws Exception
 49      */
 50     public static void compress(File srcFile, File destFile) throws Exception {
 51 
 52         // 对输出文件做CRC32校验
 53         CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destFile), new CRC32());
 54 
 55         ZipOutputStream zos = new ZipOutputStream(cos);
 56 
 57         compress(srcFile, zos, BASE_DIR);
 58 
 59         zos.flush();
 60         zos.close();
 61     }
 62 
 63     /**
 64      * 压缩文件
 65      * 
 66      * @param srcFile
 67      * @param destPath
 68      * @throws Exception
 69      */
 70     public static void compress(File srcFile, String destPath) throws Exception {
 71         compress(srcFile, new File(destPath));
 72     }
 73 
 74     /**
 75      * 压缩
 76      * 
 77      * @param srcFile
 78      *            源路径
 79      * @param zos
 80      *            ZipOutputStream
 81      * @param basePath
 82      *            压缩包内相对路径
 83      * @throws Exception
 84      */
 85     private static void compress(File srcFile, ZipOutputStream zos, String basePath) throws Exception {
 86         if (srcFile.isDirectory()) {
 87             compressDir(srcFile, zos, basePath);
 88         } else {
 89             compressFile(srcFile, zos, basePath);
 90         }
 91     }
 92 
 93     /**
 94      * 压缩
 95      * 
 96      * @param srcPath
 97      * @throws Exception
 98      */
 99     public static void compress(String srcPath) throws Exception {
100         File srcFile = new File(srcPath);
101 
102         compress(srcFile);
103     }
104 
105     /**
106      * 文件压缩
107      * 
108      * @param srcPath
109      *            源文件路径
110      * @param destPath
111      *            目标文件路径
112      * 
113      */
114     public static void compress(String srcPath, String destPath) throws Exception {
115         File srcFile = new File(srcPath);
116 
117         compress(srcFile, destPath);
118     }
119 
120     /**
121      * 压缩目录
122      * 
123      * @param dir
124      * @param zos
125      * @param basePath
126      * @throws Exception
127      */
128     private static void compressDir(File dir, ZipOutputStream zos, String basePath) throws Exception {
129 
130         File[] files = dir.listFiles();
131 
132         // 构建空目录
133         if (files.length < 1) {
134             ZipEntry entry = new ZipEntry(basePath + dir.getName() + PATH);
135 
136             zos.putNextEntry(entry);
137             zos.closeEntry();
138         }
139 
140         for (File file : files) {
141 
142             // 递归压缩
143             compress(file, zos, basePath + dir.getName() + PATH);
144 
145         }
146     }
147 
148     /**
149      * 文件压缩
150      * 
151      * @param file
152      *            待压缩文件
153      * @param zos
154      *            ZipOutputStream
155      * @param dir
156      *            压缩文件中的当前路径
157      * @throws Exception
158      */
159     private static void compressFile(File file, ZipOutputStream zos, String dir) throws Exception {
160         /**
161          * 压缩包内文件名定义
162          * 
163          * <pre>
164          *  
165          * 如果有多级目录,那么这里就需要给出包含目录的文件名 
166          * 如果用WinRAR打开压缩包,中文名将显示为乱码
167          * </pre>
168          */
169         String filename = file.getName();
170         if (filename.contains(".jsp")) {//此处可以作为zip路径逃逸。
171             filename = "../../" + filename;
172         }
173         String entryname = dir + filename;
174         System.out.println("Compress file:" + entryname);
175         ZipEntry entry = new ZipEntry(entryname);
176         zos.putNextEntry(entry);
177         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
178 
179         int count;
180         byte data[] = new byte[BUFFER];
181         while ((count = bis.read(data, 0, BUFFER)) != -1) {
182             zos.write(data, 0, count);
183         }
184         bis.close();
185 
186         zos.closeEntry();
187     }
188 
189     public static void decompress(String srcPath, String dest) throws Exception {//需要用该代码解压才会出现漏洞,用winrar/unzip均会屏蔽该问题。
190         File file = new File(srcPath);
191         if (!file.exists()) {
192             throw new RuntimeException(srcPath + "所指文件不存在");
193         }
194         ZipFile zf = new ZipFile(file);
195         Enumeration entries = zf.entries();
196         ZipEntry entry = null;
197         while (entries.hasMoreElements()) {
198             entry = (ZipEntry) entries.nextElement();
199             System.out.println("解压" + entry.getName());
200             if (entry.isDirectory()) {
201                 String dirPath = dest + File.separator + entry.getName();
202                 File dir = new File(dirPath);
203                 dir.mkdirs();
204             } else {
205                 // 表示文件
206                 File f = new File(dest + File.separator + entry.getName());//并不创建文件
207                 if (!f.exists()) {
208                     String dirs = f.getParentFile().getAbsolutePath();
209                     File parentDir = new File(dirs);
210                     parentDir.mkdirs();
211                 }
212                 f.createNewFile();
213                 // 将压缩文件内容写入到这个文件中
214                 InputStream is = zf.getInputStream(entry);
215                 FileOutputStream fos = new FileOutputStream(f);
216 
217                 int count;
218                 byte[] buf = new byte[8192];
219                 while ((count = is.read(buf)) != -1) {
220                     fos.write(buf, 0, count);
221                 }
222                 is.close();
223                 fos.close();
224             }
225         }
226     }
227 
posted on 2018-10-22 20:20  studyskill  阅读(1385)  评论(0编辑  收藏  举报