有一个好的工具,会让你的开发事半功倍。上传,可以说是下载的逆过程。
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 = "上传文件扩展名是不允许的扩展名。\n只允许" + 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/
感谢您的阅读。如果文章对您有用,那么请轻轻点个赞,以资鼓励。