文件上传工具类源码

  有一个好的工具,会让你的开发事半功倍。上传,可以说是下载的逆过程。

  1 import java.io.File;
  2 import java.io.IOException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.ArrayList;
  5 import java.util.Arrays;
  6 import java.util.Date;
  7 import java.util.HashMap;
  8 import java.util.Iterator;
  9 import java.util.List;
 10 import java.util.Map;
 11 import java.util.Random;
 12 
 13 import javax.servlet.http.HttpServletRequest;
 14 
 15 import org.apache.commons.fileupload.FileItem;
 16 import org.apache.commons.fileupload.FileUploadException;
 17 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 18 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 19 
 20 /**
 21  * 文件上传工具类
 22  * 
 23  */
 24 public class UploadUtils {
 25     /**
 26      * 表单字段常量
 27      */
 28     public static final String FORM_FIELDS = "form_fields";
 29     /**
 30      * 文件域常量
 31      */
 32     public static final String FILE_FIELDS = "file_fields";
 33 
 34     // 最大文件大小
 35     private long maxSize = 1000000;
 36     // 定义允许上传的文件扩展名
 37     private Map<String, String> extMap = new HashMap<String, String>();
 38     // 文件保存目录相对路径
 39     private String basePath = "upload";
 40     // 文件的目录名
 41     private String dirName = "images";
 42     // 上传临时路径
 43     private static final String TEMP_PATH = "/temp";
 44     private String tempPath = basePath + TEMP_PATH;
 45     // 若不指定则文件名默认为 yyyyMMddHHmmss_xyz
 46     private String fileName;
 47 
 48     // 文件保存目录路径
 49     private String savePath;
 50     // 文件保存目录url
 51     private String saveUrl;
 52     // 文件最终的url包括文件名
 53     private String fileUrl;
 54 
 55     public UploadUtils() {
 56         // 其中images,flashs,medias,files,对应文件夹名称,对应dirName
 57         // key文件夹名称
 58         // value该文件夹内可以上传文件的后缀名
 59         extMap.put("images", "gif,jpg,jpeg,png,bmp");
 60         extMap.put("flashs", "swf,flv");
 61         extMap.put("medias", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
 62         extMap.put("files", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
 63     }
 64 
 65     /**
 66      * 文件上传
 67      * 
 68      * @param request
 69      * @return infos info[0] 验证文件域返回错误信息 info[1] 上传文件错误信息 info[2] savePath info[3] saveUrl info[4] fileUrl
 70      */
 71     @SuppressWarnings("unchecked")
 72     public String[] uploadFile(HttpServletRequest request) {
 73         String[] infos = new String[5];
 74         // 验证
 75         infos[0] = this.validateFields(request);
 76         // 初始化表单元素
 77         Map<String, Object> fieldsMap = new HashMap<String, Object>();
 78         if (infos[0].equals("true")) {
 79             fieldsMap = this.initFields(request);
 80         }
 81         // 上传
 82         List<FileItem> fiList = (List<FileItem>) fieldsMap.get(UploadUtils.FILE_FIELDS);
 83         if (fiList != null) {
 84             for (FileItem item : fiList) {
 85                 infos[1] = this.saveFile(item);
 86             }
 87             infos[2] = savePath;
 88             infos[3] = saveUrl;
 89             infos[4] = fileUrl;
 90         }
 91         return infos;
 92     }
 93 
 94     /**
 95      * 上传验证,并初始化文件目录
 96      * 
 97      * @param request
 98      */
 99     private String validateFields(HttpServletRequest request) {
100         String errorInfo = "true";
101         // boolean errorFlag = true;
102         // 获取内容类型
103         String contentType = request.getContentType();
104         int contentLength = request.getContentLength();
105         // 文件保存目录路径
106         savePath = request.getSession().getServletContext().getRealPath("/") + basePath + "/";
107         // 文件保存目录URL
108         saveUrl = request.getContextPath() + "/" + basePath + "/";
109         File uploadDir = new File(savePath);
110         if (contentType == null || !contentType.startsWith("multipart")) {
111             // TODO
112             System.out.println("请求不包含multipart/form-data流");
113             errorInfo = "请求不包含multipart/form-data流";
114         } else if (maxSize < contentLength) {
115             // TODO
116             System.out.println("上传文件大小超出文件最大大小");
117             errorInfo = "上传文件大小超出文件最大大小[" + maxSize + "]";
118         } else if (!ServletFileUpload.isMultipartContent(request)) {
119             // TODO
120             errorInfo = "请选择文件";
121         } else if (!uploadDir.isDirectory()) {// 检查目录
122             // TODO
123             errorInfo = "上传目录[" + savePath + "]不存在";
124         } else if (!uploadDir.canWrite()) {
125             // TODO
126             errorInfo = "上传目录[" + savePath + "]没有写权限";
127         } else if (!extMap.containsKey(dirName)) {
128             // TODO
129             errorInfo = "目录名不正确";
130         } else {
131             // .../basePath/dirName/
132             // 创建文件夹
133             savePath += dirName + "/";
134             saveUrl += dirName + "/";
135             File saveDirFile = new File(savePath);
136             if (!saveDirFile.exists()) {
137                 saveDirFile.mkdirs();
138             }
139             // .../basePath/dirName/yyyyMMdd/
140             SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
141             String ymd = sdf.format(new Date());
142             savePath += ymd + "/";
143             saveUrl += ymd + "/";
144             File dirFile = new File(savePath);
145             if (!dirFile.exists()) {
146                 dirFile.mkdirs();
147             }
148 
149             // 获取上传临时路径
150             tempPath = request.getSession().getServletContext().getRealPath("/") + tempPath + "/";
151             File file = new File(tempPath);
152             if (!file.exists()) {
153                 file.mkdirs();
154             }
155         }
156 
157         return errorInfo;
158     }
159 
160     /**
161      * 处理上传内容
162      * 
163      * @param request
164      * @param maxSize
165      * @return
166      */
167 //    @SuppressWarnings("unchecked")
168     private Map<String, Object> initFields(HttpServletRequest request) {
169 
170         // 存储表单字段和非表单字段
171         Map<String, Object> map = new HashMap<String, Object>();
172 
173         // 第一步:判断request
174         boolean isMultipart = ServletFileUpload.isMultipartContent(request);
175         // 第二步:解析request
176         if (isMultipart) {
177             // Create a factory for disk-based file items
178             DiskFileItemFactory factory = new DiskFileItemFactory();
179 
180             // 阀值,超过这个值才会写到临时目录,否则在内存中
181             factory.setSizeThreshold(1024 * 1024 * 10);
182             factory.setRepository(new File(tempPath));
183 
184             // Create a new file upload handler
185             ServletFileUpload upload = new ServletFileUpload(factory);
186 
187             upload.setHeaderEncoding("UTF-8");
188 
189             // 最大上传限制
190             upload.setSizeMax(maxSize);
191 
192             /* FileItem */
193             List<FileItem> items = null;
194             // Parse the request
195             try {
196                 items = upload.parseRequest(request);
197             } catch (FileUploadException e) {
198                 // TODO Auto-generated catch block
199                 e.printStackTrace();
200             }
201 
202             // 第3步:处理uploaded items
203             if (items != null && items.size() > 0) {
204                 Iterator<FileItem> iter = items.iterator();
205                 // 文件域对象
206                 List<FileItem> list = new ArrayList<FileItem>();
207                 // 表单字段
208                 Map<String, String> fields = new HashMap<String, String>();
209                 while (iter.hasNext()) {
210                     FileItem item = iter.next();
211                     // 处理所有表单元素和文件域表单元素
212                     if (item.isFormField()) { // 表单元素
213                         String name = item.getFieldName();
214                         String value = item.getString();
215                         fields.put(name, value);
216                     } else { // 文件域表单元素
217                         list.add(item);
218                     }
219                 }
220                 map.put(FORM_FIELDS, fields);
221                 map.put(FILE_FIELDS, list);
222             }
223         }
224         return map;
225     }
226 
227     /**
228      * 保存文件
229      * 
230      * @param obj
231      *            要上传的文件域
232      * @param file
233      * @return
234      */
235     private String saveFile(FileItem item) {
236         String error = "true";
237         String fileName = item.getName();
238         String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
239 
240         if (item.getSize() > maxSize) { // 检查文件大小
241             // TODO
242             error = "上传文件大小超过限制";
243         } else if (!Arrays.<String> asList(extMap.get(dirName).split(",")).contains(fileExt)) {// 检查扩展名
244             error = "上传文件扩展名是不允许的扩展名。
只允许" + extMap.get(dirName) + "格式。";
245         } else {
246             String newFileName;
247             if ("".equals(fileName.trim())) {
248                 SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
249                 newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
250             } else {
251                 newFileName = fileName + "." + fileExt;
252             }
253             // .../basePath/dirName/yyyyMMdd/yyyyMMddHHmmss_xxx.xxx
254             fileUrl = saveUrl + newFileName;
255             try {
256                 File uploadedFile = new File(savePath, newFileName);
257 
258                 item.write(uploadedFile);
259 
260                 /*
261                  * FileOutputStream fos = new FileOutputStream(uploadFile); // 文件全在内存中 if (item.isInMemory()) { fos.write(item.get()); } else { InputStream is = item.getInputStream(); byte[] buffer =
262                  * new byte[1024]; int len; while ((len = is.read(buffer)) > 0) { fos.write(buffer, 0, len); } is.close(); } fos.close(); item.delete();
263                  */
264             } catch (IOException e) {
265                 e.printStackTrace();
266                 System.out.println("上传失败了!!!");
267             } catch (Exception e) {
268                 e.printStackTrace();
269             }
270         }
271         return error;
272     }
273 
274     /** **********************get/set方法********************************* */
275 
276     public String getSavePath() {
277         return savePath;
278     }
279 
280     public String getSaveUrl() {
281         return saveUrl;
282     }
283 
284     public long getMaxSize() {
285         return maxSize;
286     }
287 
288     public void setMaxSize(long maxSize) {
289         this.maxSize = maxSize;
290     }
291 
292     public Map<String, String> getExtMap() {
293         return extMap;
294     }
295 
296     public void setExtMap(Map<String, String> extMap) {
297         this.extMap = extMap;
298     }
299 
300     public String getBasePath() {
301         return basePath;
302     }
303 
304     public void setBasePath(String basePath) {
305         this.basePath = basePath;
306         tempPath = basePath + TEMP_PATH;
307     }
308 
309     public String getDirName() {
310         return dirName;
311     }
312 
313     public void setDirName(String dirName) {
314         this.dirName = dirName;
315     }
316 
317     public String getTempPath() {
318         return tempPath;
319     }
320 
321     public void setTempPath(String tempPath) {
322         this.tempPath = tempPath;
323     }
324 
325     public String getFileUrl() {
326         return fileUrl;
327     }
328 
329     public String getFileName() {
330         return fileName;
331     }
332 
333     public void setFileName(String fileName) {
334         this.fileName = fileName;
335     }
336 
337 }

  既然你要上传,那对文件的操作就不可避免了。

  1 import java.io.File;
  2 import java.io.FileInputStream;
  3 import java.io.FileOutputStream;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.OutputStream;
  7 import java.util.Enumeration;
  8 
  9 import org.apache.tools.zip.ZipEntry;
 10 import org.apache.tools.zip.ZipFile;
 11 import org.apache.tools.zip.ZipOutputStream;
 12 import org.slf4j.Logger;
 13 import org.slf4j.LoggerFactory;
 14 
 15 /**
 16  * 文件操作工具类
 17  * 实现文件的创建、删除、复制、压缩、解压以及目录的创建、删除、复制、压缩解压等功能
 18  */
 19 public class FileUtils extends org.apache.commons.io.FileUtils {
 20     
 21     private static Logger log = LoggerFactory.getLogger(FileUtils.class);
 22 
 23     /**
 24      * 复制单个文件,如果目标文件存在,则不覆盖
 25      * @param srcFileName 待复制的文件名
 26      * @param descFileName 目标文件名
 27      * @return 如果复制成功,则返回true,否则返回false
 28      */
 29     public static boolean copyFile(String srcFileName, String descFileName) {
 30         return FileUtils.copyFileCover(srcFileName, descFileName, false);
 31     }
 32 
 33     /**
 34      * 复制单个文件
 35      * @param srcFileName 待复制的文件名
 36      * @param descFileName 目标文件名
 37      * @param coverlay 如果目标文件已存在,是否覆盖
 38      * @return 如果复制成功,则返回true,否则返回false
 39      */
 40     public static boolean copyFileCover(String srcFileName,
 41             String descFileName, boolean coverlay) {
 42         File srcFile = new File(srcFileName);
 43         // 判断源文件是否存在
 44         if (!srcFile.exists()) {
 45             log.debug("复制文件失败,源文件 " + srcFileName + " 不存在!");
 46             return false;
 47         }
 48         // 判断源文件是否是合法的文件
 49         else if (!srcFile.isFile()) {
 50             log.debug("复制文件失败," + srcFileName + " 不是一个文件!");
 51             return false;
 52         }
 53         File descFile = new File(descFileName);
 54         // 判断目标文件是否存在
 55         if (descFile.exists()) {
 56             // 如果目标文件存在,并且允许覆盖
 57             if (coverlay) {
 58                 log.debug("目标文件已存在,准备删除!");
 59                 if (!FileUtils.delFile(descFileName)) {
 60                     log.debug("删除目标文件 " + descFileName + " 失败!");
 61                     return false;
 62                 }
 63             } else {
 64                 log.debug("复制文件失败,目标文件 " + descFileName + " 已存在!");
 65                 return false;
 66             }
 67         } else {
 68             if (!descFile.getParentFile().exists()) {
 69                 // 如果目标文件所在的目录不存在,则创建目录
 70                 log.debug("目标文件所在的目录不存在,创建目录!");
 71                 // 创建目标文件所在的目录
 72                 if (!descFile.getParentFile().mkdirs()) {
 73                     log.debug("创建目标文件所在的目录失败!");
 74                     return false;
 75                 }
 76             }
 77         }
 78 
 79         // 准备复制文件
 80         // 读取的位数
 81         int readByte = 0;
 82         InputStream ins = null;
 83         OutputStream outs = null;
 84         try {
 85             // 打开源文件
 86             ins = new FileInputStream(srcFile);
 87             // 打开目标文件的输出流
 88             outs = new FileOutputStream(descFile);
 89             byte[] buf = new byte[1024];
 90             // 一次读取1024个字节,当readByte为-1时表示文件已经读取完毕
 91             while ((readByte = ins.read(buf)) != -1) {
 92                 // 将读取的字节流写入到输出流
 93                 outs.write(buf, 0, readByte);
 94             }
 95             log.debug("复制单个文件 " + srcFileName + " 到" + descFileName
 96                     + "成功!");
 97             return true;
 98         } catch (Exception e) {
 99             log.debug("复制文件失败:" + e.getMessage());
100             return false;
101         } finally {
102             // 关闭输入输出流,首先关闭输出流,然后再关闭输入流
103             if (outs != null) {
104                 try {
105                     outs.close();
106                 } catch (IOException oute) {
107                     oute.printStackTrace();
108                 }
109             }
110             if (ins != null) {
111                 try {
112                     ins.close();
113                 } catch (IOException ine) {
114                     ine.printStackTrace();
115                 }
116             }
117         }
118     }
119 
120     /**
121      * 复制整个目录的内容,如果目标目录存在,则不覆盖
122      * @param srcDirName 源目录名
123      * @param descDirName 目标目录名
124      * @return 如果复制成功返回true,否则返回false
125      */
126     public static boolean copyDirectory(String srcDirName, String descDirName) {
127         return FileUtils.copyDirectoryCover(srcDirName, descDirName,
128                 false);
129     }
130 
131     /**
132      * 复制整个目录的内容 
133      * @param srcDirName 源目录名
134      * @param descDirName 目标目录名
135      * @param coverlay 如果目标目录存在,是否覆盖
136      * @return 如果复制成功返回true,否则返回false
137      */
138     public static boolean copyDirectoryCover(String srcDirName,
139             String descDirName, boolean coverlay) {
140         File srcDir = new File(srcDirName);
141         // 判断源目录是否存在
142         if (!srcDir.exists()) {
143             log.debug("复制目录失败,源目录 " + srcDirName + " 不存在!");
144             return false;
145         }
146         // 判断源目录是否是目录
147         else if (!srcDir.isDirectory()) {
148             log.debug("复制目录失败," + srcDirName + " 不是一个目录!");
149             return false;
150         }
151         // 如果目标文件夹名不以文件分隔符结尾,自动添加文件分隔符
152         String descDirNames = descDirName;
153         if (!descDirNames.endsWith(File.separator)) {
154             descDirNames = descDirNames + File.separator;
155         }
156         File descDir = new File(descDirNames);
157         // 如果目标文件夹存在
158         if (descDir.exists()) {
159             if (coverlay) {
160                 // 允许覆盖目标目录
161                 log.debug("目标目录已存在,准备删除!");
162                 if (!FileUtils.delFile(descDirNames)) {
163                     log.debug("删除目录 " + descDirNames + " 失败!");
164                     return false;
165                 }
166             } else {
167                 log.debug("目标目录复制失败,目标目录 " + descDirNames + " 已存在!");
168                 return false;
169             }
170         } else {
171             // 创建目标目录
172             log.debug("目标目录不存在,准备创建!");
173             if (!descDir.mkdirs()) {
174                 log.debug("创建目标目录失败!");
175                 return false;
176             }
177 
178         }
179 
180         boolean flag = true;
181         // 列出源目录下的所有文件名和子目录名
182         File[] files = srcDir.listFiles();
183         for (int i = 0; i < files.length; i++) {
184             // 如果是一个单个文件,则直接复制
185             if (files[i].isFile()) {
186                 flag = FileUtils.copyFile(files[i].getAbsolutePath(),
187                         descDirName + files[i].getName());
188                 // 如果拷贝文件失败,则退出循环
189                 if (!flag) {
190                     break;
191                 }
192             }
193             // 如果是子目录,则继续复制目录
194             if (files[i].isDirectory()) {
195                 flag = FileUtils.copyDirectory(files[i]
196                         .getAbsolutePath(), descDirName + files[i].getName());
197                 // 如果拷贝目录失败,则退出循环
198                 if (!flag) {
199                     break;
200                 }
201             }
202         }
203 
204         if (!flag) {
205             log.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 失败!");
206             return false;
207         }
208         log.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 成功!");
209         return true;
210 
211     }
212 
213     /**
214      * 
215      * 删除文件,可以删除单个文件或文件夹
216      * 
217      * @param fileName 被删除的文件名
218      * @return 如果删除成功,则返回true,否是返回false
219      */
220     public static boolean delFile(String fileName) {
221          File file = new File(fileName);
222         if (!file.exists()) {
223             log.debug(fileName + " 文件不存在!");
224             return true;
225         } else {
226             if (file.isFile()) {
227                 return FileUtils.deleteFile(fileName);
228             } else {
229                 return FileUtils.deleteDirectory(fileName);
230             }
231         }
232     }
233 
234     /**
235      * 
236      * 删除单个文件
237      * 
238      * @param fileName 被删除的文件名
239      * @return 如果删除成功,则返回true,否则返回false
240      */
241     public static boolean deleteFile(String fileName) {
242         File file = new File(fileName);
243         if (file.exists() && file.isFile()) {
244             if (file.delete()) {
245                 log.debug("删除文件 " + fileName + " 成功!");
246                 return true;
247             } else {
248                 log.debug("删除文件 " + fileName + " 失败!");
249                 return false;
250             }
251         } else {
252             log.debug(fileName + " 文件不存在!");
253             return true;
254         }
255     }
256 
257     /**
258      * 
259      * 删除目录及目录下的文件
260      * 
261      * @param dirName 被删除的目录所在的文件路径
262      * @return 如果目录删除成功,则返回true,否则返回false
263      */
264     public static boolean deleteDirectory(String dirName) {
265         String dirNames = dirName;
266         if (!dirNames.endsWith(File.separator)) {
267             dirNames = dirNames + File.separator;
268         }
269         File dirFile = new File(dirNames);
270         if (!dirFile.exists() || !dirFile.isDirectory()) {
271             log.debug(dirNames + " 目录不存在!");
272             return true;
273         }
274         boolean flag = true;
275         // 列出全部文件及子目录
276         File[] files = dirFile.listFiles();
277         for (int i = 0; i < files.length; i++) {
278             // 删除子文件
279             if (files[i].isFile()) {
280                 flag = FileUtils.deleteFile(files[i].getAbsolutePath());
281                 // 如果删除文件失败,则退出循环
282                 if (!flag) {
283                     break;
284                 }
285             }
286             // 删除子目录
287             else if (files[i].isDirectory()) {
288                 flag = FileUtils.deleteDirectory(files[i]
289                         .getAbsolutePath());
290                 // 如果删除子目录失败,则退出循环
291                 if (!flag) {
292                     break;
293                 }
294             }
295         }
296 
297         if (!flag) {
298             log.debug("删除目录失败!");
299             return false;
300         }
301         // 删除当前目录
302         if (dirFile.delete()) {
303             log.debug("删除目录 " + dirName + " 成功!");
304             return true;
305         } else {
306             log.debug("删除目录 " + dirName + " 失败!");
307             return false;
308         }
309 
310     }
311 
312     /**
313      * 创建单个文件
314      * @param descFileName 文件名,包含路径
315      * @return 如果创建成功,则返回true,否则返回false
316      */
317     public static boolean createFile(String descFileName) {
318         File file = new File(descFileName);
319         if (file.exists()) {
320             log.debug("文件 " + descFileName + " 已存在!");
321             return false;
322         }
323         if (descFileName.endsWith(File.separator)) {
324             log.debug(descFileName + " 为目录,不能创建目录!");
325             return false;
326         }
327         if (!file.getParentFile().exists()) {
328             // 如果文件所在的目录不存在,则创建目录
329             if (!file.getParentFile().mkdirs()) {
330                 log.debug("创建文件所在的目录失败!");
331                 return false;
332             }
333         }
334 
335         // 创建文件
336         try {
337             if (file.createNewFile()) {
338                 log.debug(descFileName + " 文件创建成功!");
339                 return true;
340             } else {
341                 log.debug(descFileName + " 文件创建失败!");
342                 return false;
343             }
344         } catch (Exception e) {
345             e.printStackTrace();
346             log.debug(descFileName + " 文件创建失败!");
347             return false;
348         }
349 
350     }
351 
352     /**
353      * 创建目录
354      * @param descDirName 目录名,包含路径
355      * @return 如果创建成功,则返回true,否则返回false
356      */
357     public static boolean createDirectory(String descDirName) {
358         String descDirNames = descDirName;
359         if (!descDirNames.endsWith(File.separator)) {
360             descDirNames = descDirNames + File.separator;
361         }
362         File descDir = new File(descDirNames);
363         if (descDir.exists()) {
364             log.debug("目录 " + descDirNames + " 已存在!");
365             return false;
366         }
367         // 创建目录
368         if (descDir.mkdirs()) {
369             log.debug("目录 " + descDirNames + " 创建成功!");
370             return true;
371         } else {
372             log.debug("目录 " + descDirNames + " 创建失败!");
373             return false;
374         }
375 
376     }
377 
378     /**
379      * 写入文件
380      * @param file 要写入的文件
381      */
382     public static void writeToFile(String fileName, String content, boolean append) {
383         try {
384             FileUtils.write(new File(fileName), content, "utf-8", append);
385             log.debug("文件 " + fileName + " 写入成功!");
386         } catch (IOException e) {
387             log.debug("文件 " + fileName + " 写入失败! " + e.getMessage());
388         }
389     }
390 
391     /**
392      * 写入文件
393      * @param file 要写入的文件
394      */
395     public static void writeToFile(String fileName, String content, String encoding, boolean append) {
396         try {
397             FileUtils.write(new File(fileName), content, encoding, append);
398             log.debug("文件 " + fileName + " 写入成功!");
399         } catch (IOException e) {
400             log.debug("文件 " + fileName + " 写入失败! " + e.getMessage());
401         }
402     }
403     
404     /**
405      * 压缩文件或目录
406      * @param srcDirName 压缩的根目录
407      * @param fileName 根目录下的待压缩的文件名或文件夹名,其中*或""表示跟目录下的全部文件
408      * @param descFileName 目标zip文件
409      */
410     public static void zipFiles(String srcDirName, String fileName,
411             String descFileName) {
412         // 判断目录是否存在
413         if (srcDirName == null) {
414             log.debug("文件压缩失败,目录 " + srcDirName + " 不存在!");
415             return;
416         }
417         File fileDir = new File(srcDirName);
418         if (!fileDir.exists() || !fileDir.isDirectory()) {
419             log.debug("文件压缩失败,目录 " + srcDirName + " 不存在!");
420             return;
421         }
422         String dirPath = fileDir.getAbsolutePath();
423         File descFile = new File(descFileName);
424         try {
425             ZipOutputStream zouts = new ZipOutputStream(new FileOutputStream(
426                     descFile));
427             if ("*".equals(fileName) || "".equals(fileName)) {
428                 FileUtils.zipDirectoryToZipFile(dirPath, fileDir, zouts);
429             } else {
430                 File file = new File(fileDir, fileName);
431                 if (file.isFile()) {
432                     FileUtils.zipFilesToZipFile(dirPath, file, zouts);
433                 } else {
434                     FileUtils
435                             .zipDirectoryToZipFile(dirPath, file, zouts);
436                 }
437             }
438             zouts.close();
439             log.debug(descFileName + " 文件压缩成功!");
440         } catch (Exception e) {
441             log.debug("文件压缩失败:" + e.getMessage());
442             e.printStackTrace();
443         }
444 
445     }
446 
447     /**
448      * 解压缩ZIP文件,将ZIP文件里的内容解压到descFileName目录下
449      * @param zipFileName 需要解压的ZIP文件
450      * @param descFileName 目标文件
451      */
452     public static boolean unZipFiles(String zipFileName, String descFileName) {
453         String descFileNames = descFileName;
454         if (!descFileNames.endsWith(File.separator)) {
455             descFileNames = descFileNames + File.separator;
456         }        
457         try {
458             // 根据ZIP文件创建ZipFile对象
459             ZipFile zipFile = new ZipFile(zipFileName);
460             ZipEntry entry = null;
461             String entryName = null;
462             String descFileDir = null;
463             byte[] buf = new byte[4096];
464             int readByte = 0;
465             // 获取ZIP文件里所有的entry
466             @SuppressWarnings("rawtypes")
467             Enumeration enums = zipFile.getEntries();
468             // 遍历所有entry
469             while (enums.hasMoreElements()) {
470                 entry = (ZipEntry) enums.nextElement();
471                 // 获得entry的名字
472                 entryName = entry.getName();
473                 descFileDir = descFileNames + entryName;
474                 if (entry.isDirectory()) {
475                     // 如果entry是一个目录,则创建目录
476                     new File(descFileDir).mkdirs();
477                     continue;
478                 } else {
479                     // 如果entry是一个文件,则创建父目录
480                     new File(descFileDir).getParentFile().mkdirs();
481                 }
482                 File file = new File(descFileDir);
483                 // 打开文件输出流
484                 OutputStream os = new FileOutputStream(file);
485                 // 从ZipFile对象中打开entry的输入流
486                 InputStream is = zipFile.getInputStream(entry);
487                 while ((readByte = is.read(buf)) != -1) {
488                     os.write(buf, 0, readByte);
489                 }
490                 os.close();
491                 is.close();
492             }
493             zipFile.close();
494             log.debug("文件解压成功!");
495             return true;
496         } catch (Exception e) {
497             log.debug("文件解压失败:" + e.getMessage());
498             return false;
499         }
500     }
501 
502     /**
503      * 将目录压缩到ZIP输出流
504      * @param dirPath 目录路径
505      * @param fileDir 文件信息
506      * @param zouts 输出流
507      */
508     public static void zipDirectoryToZipFile(String dirPath, File fileDir,
509             ZipOutputStream zouts) {
510         if (fileDir.isDirectory()) {
511             File[] files = fileDir.listFiles();
512             // 空的文件夹
513             if (files.length == 0) {
514                 // 目录信息
515                 ZipEntry entry = new ZipEntry(getEntryName(dirPath, fileDir));
516                 try {
517                     zouts.putNextEntry(entry);
518                     zouts.closeEntry();
519                 } catch (Exception e) {
520                     e.printStackTrace();
521                 }
522                 return;
523             }
524 
525             for (int i = 0; i < files.length; i++) {
526                 if (files[i].isFile()) {
527                     // 如果是文件,则调用文件压缩方法
528                     FileUtils
529                             .zipFilesToZipFile(dirPath, files[i], zouts);
530                 } else {
531                     // 如果是目录,则递归调用
532                     FileUtils.zipDirectoryToZipFile(dirPath, files[i],
533                             zouts);
534                 }
535             }
536 
537         }
538 
539     }
540 
541     /**
542      * 将文件压缩到ZIP输出流
543      * @param dirPath 目录路径
544      * @param file 文件
545      * @param zouts 输出流
546      */
547     public static void zipFilesToZipFile(String dirPath, File file,
548             ZipOutputStream zouts) {
549         FileInputStream fin = null;
550         ZipEntry entry = null;
551         // 创建复制缓冲区
552         byte[] buf = new byte[4096];
553         int readByte = 0;
554         if (file.isFile()) {
555             try {
556                 // 创建一个文件输入流
557                 fin = new FileInputStream(file);
558                 // 创建一个ZipEntry
559                 entry = new ZipEntry(getEntryName(dirPath, file));
560                 // 存储信息到压缩文件
561                 zouts.putNextEntry(entry);
562                 // 复制字节到压缩文件
563                 while ((readByte = fin.read(buf)) != -1) {
564                     zouts.write(buf, 0, readByte);
565                 }
566                 zouts.closeEntry();
567                 fin.close();
568                 System.out
569                         .println("添加文件 " + file.getAbsolutePath() + " 到zip文件中!");
570             } catch (Exception e) {
571                 e.printStackTrace();
572             }
573         }
574 
575     }
576 
577     /**
578      * 获取待压缩文件在ZIP文件中entry的名字,即相对于跟目录的相对路径名
579      * @param dirPat 目录名
580      * @param file entry文件名
581      * @return
582      */
583     private static String getEntryName(String dirPath, File file) {
584         String dirPaths = dirPath;
585         if (!dirPaths.endsWith(File.separator)) {
586             dirPaths = dirPaths + File.separator;
587         }
588         String filePath = file.getAbsolutePath();
589         // 对于目录,必须在entry名字后面加上"/",表示它将以目录项存储
590         if (file.isDirectory()) {
591             filePath += "/";
592         }
593         int index = filePath.indexOf(dirPaths);
594 
595         return filePath.substring(index + dirPaths.length());
596     }
597     
598      /**
599       * 修复路径,将 \ 或 / 等替换为 File.separator 
600       * @param path
601       * @return
602       */
603      public static String path(String path){
604          String p = StringUtils.replace(path, "\", "/");
605          p = StringUtils.join(StringUtils.split(p, "/"), "/");
606          if (!StringUtils.startsWithAny(p, "/") && StringUtils.startsWithAny(path, "\", "/")){
607              p += "/";
608          }
609          if (!StringUtils.endsWithAny(p, "/") && StringUtils.endsWithAny(path, "\", "/")){
610              p = p + "/";
611          }
612          return p;
613      }
614 
615 }

转载请注明出处!

http://www.cnblogs.com/libingbin/

感谢您的阅读。如果文章对您有用,那么请轻轻点个赞,以资鼓励。

原文地址:https://www.cnblogs.com/libingbin/p/6033004.html