ZipFileOperator.java 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package com.primeton.damp.utils;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import java.io.*;
  5. import java.util.ArrayList;
  6. import java.util.Enumeration;
  7. import java.util.List;
  8. import java.util.zip.ZipEntry;
  9. import java.util.zip.ZipFile;
  10. import java.util.zip.ZipOutputStream;
  11. public class ZipFileOperator {
  12. /**
  13. * 日志记录
  14. *
  15. */
  16. private static Logger log = LoggerFactory.getLogger(ZipFileOperator.class);
  17. /**
  18. * 压缩指定文件集.
  19. * @param compressFilePath 压缩后的zip文件保存的路径
  20. * @param filesPath 需要被压缩的文件或者文件夹集合
  21. * @return 返回压缩后的文件
  22. * @throws IOException 压缩异常
  23. */
  24. public File compressZip(String compressFilePath, String... filesPath) throws IOException {
  25. return compressZip(new File(compressFilePath), filesPath);
  26. }
  27. /**
  28. * 压缩指定文件集.
  29. *
  30. * @param files
  31. * 被压缩的文件集合
  32. * @param compressFile
  33. * 压缩后的zip文件保存的路径
  34. * @return 返回压缩后的文件
  35. * @throws IOException
  36. * 压缩异常
  37. */
  38. public File compressZip(File compressFile, String... files)
  39. throws IOException {
  40. if (!compressFile.exists()) {
  41. if (!compressFile.getParentFile().exists()) {
  42. if (!compressFile.getParentFile().mkdirs()) {
  43. StringBuilder exception = new StringBuilder();
  44. exception.append("系统找不到指定的路径: ");
  45. exception.append(compressFile.getParentFile().getAbsolutePath());
  46. exception.append("并且创建: ");
  47. exception.append(compressFile.getAbsolutePath());
  48. exception.append("失败!");
  49. throw new IOException(exception.toString());
  50. }
  51. }
  52. if (!compressFile.createNewFile()) {
  53. StringBuilder exception = new StringBuilder();
  54. exception.append("创建文件: ");
  55. exception.append(compressFile.getAbsolutePath());
  56. exception.append("失败!");
  57. throw new IOException(exception.toString());
  58. }
  59. }
  60. ZipOutputStream zos = null;
  61. try {
  62. zos = new ZipOutputStream(
  63. new FileOutputStream(compressFile));
  64. for (String fileName : files) {
  65. File compFile = new File(fileName);
  66. if(compFile.exists()){
  67. compressZip0(zos, compFile, compFile.getName());
  68. }
  69. }
  70. // 当压缩完成,关闭流
  71. zos.closeEntry();
  72. } catch(Exception e) {
  73. log.warn("压缩文件异常。", e);
  74. } finally {
  75. if(zos != null){
  76. zos.close();
  77. }
  78. }
  79. return compressFile;
  80. }
  81. /**
  82. * 递归压缩
  83. * @param zos
  84. * @param file
  85. * @param baseDir
  86. */
  87. private void compressZip0(ZipOutputStream zos, File file, String baseDir){
  88. // 压缩文件缓冲区大小
  89. FileInputStream in = null;
  90. if(file.isFile()){
  91. try {
  92. // 生成下一个压缩节点
  93. zos.putNextEntry(new ZipEntry(baseDir));
  94. } catch (IOException e1) {
  95. log.warn("压缩文件异常。", e1);
  96. }
  97. byte[] buffere = new byte[4096];
  98. int length = 0;// 读取的长度
  99. try {
  100. in = new FileInputStream(file);
  101. while ((length = in.read(buffere)) != -1) {
  102. zos.write(buffere, 0, length);
  103. }
  104. } catch (IOException e) {
  105. log.warn("压缩文件异常。", e);
  106. } finally {
  107. // 当压缩完成,关闭流
  108. if(in != null){
  109. try{
  110. in.close();
  111. } catch(IOException e){
  112. }
  113. }
  114. }
  115. log.debug("压缩文件: " + file.getAbsolutePath() + " 成功!");
  116. return ;
  117. } else {
  118. try {
  119. zos.putNextEntry(new ZipEntry(baseDir + "/"));
  120. } catch (IOException e) {
  121. log.warn("压缩文件异常。", e);
  122. }
  123. baseDir = baseDir.length() == 0 ? "" : (baseDir + "/");
  124. File[] files = file.listFiles();
  125. // 遍历所有文件,逐个进行压缩
  126. for(File f : files){
  127. compressZip0(zos, f, baseDir + f.getName());
  128. }
  129. }
  130. }
  131. /**
  132. * 解压缩指定zip文件名.
  133. * @param zipFile zip文件名
  134. * @param uncompressPath 解压说的后要保存的文件路径,若没有,系统自动新建
  135. * @throws IOException 解压缩异常
  136. */
  137. public void uncompressZip(String zipFile, String uncompressPath)
  138. throws IOException {
  139. uncompressZip(new File(zipFile), new File(uncompressPath));
  140. }
  141. /**
  142. * 解压缩指定zip文件.
  143. *
  144. * @param zipFile
  145. * zip文件名
  146. * @param uncompressPath
  147. * 解压说的后要保存的文件路径,若没有,系统自动新建
  148. * @throws IOException 解压缩异常
  149. */
  150. public void uncompressZip(File zipFile, File uncompressPath)
  151. throws IOException {
  152. ZipFile zip = null;// 创建解压缩文件
  153. try {
  154. zip = new ZipFile(zipFile);
  155. } catch (IOException e) {
  156. log.warn("解压文件异常。", e);
  157. return;
  158. }
  159. // 如果指定的路径不存在,创建文件夹
  160. if (!uncompressPath.exists()) {
  161. if (!uncompressPath.mkdirs()) {
  162. StringBuilder exception = new StringBuilder();
  163. exception.append(uncompressPath);
  164. exception.append("路径不可到达,并且解压缩");
  165. exception.append(zipFile);
  166. exception.append("失败!");
  167. throw new IOException(exception.toString());
  168. }
  169. }
  170. // 返回 ZIP 文件条目的枚举。
  171. Enumeration<? extends ZipEntry> en = zip.entries();
  172. ZipEntry entry = null;
  173. File file = null;
  174. // 遍历每一个文件
  175. while (en.hasMoreElements()) {
  176. // 如果压缩包还有下一个文件,则循环
  177. entry = (ZipEntry) en.nextElement();
  178. if (entry.isDirectory()) {
  179. // 如果是文件夹,创建文件夹并加速循环
  180. file = new File(uncompressPath, entry.getName());
  181. file.mkdirs();
  182. continue;
  183. }
  184. // 构建文件对象
  185. file = new File(uncompressPath, entry.getName());
  186. if (!file.getParentFile().exists()) {
  187. // 如果文件对象的父目录不存在,创建文件夹
  188. if(!file.getParentFile().mkdirs()){
  189. log.debug("can not create dir: " + file.getAbsolutePath());
  190. }
  191. }
  192. InputStream in = null;
  193. FileOutputStream out = null;
  194. try {
  195. in = zip.getInputStream(entry);
  196. out = new FileOutputStream(file);
  197. byte[] bytes = new byte[2048];
  198. int size = -1;
  199. while((size = in.read(bytes)) != -1){
  200. out.write(bytes, 0, size);
  201. }
  202. out.flush();
  203. } catch (IOException e) {
  204. log.warn("解压文件异常。", e);
  205. } finally {
  206. if(in != null){
  207. try {
  208. in.close();
  209. }catch(IOException e) {
  210. }
  211. }
  212. if(out != null){
  213. try {
  214. out.close();
  215. }catch(IOException e) {
  216. }
  217. }
  218. }
  219. log.debug("解压文件:" + entry.getName() + "成功!");
  220. }
  221. try{
  222. zip.close();
  223. } catch(IOException e) {
  224. log.warn("关闭文件异常。", e);
  225. }
  226. }
  227. /**
  228. * 递归获得该文件夹下所有文件(不包括目录).
  229. * 如果该文件路径指向一个文件,则返回该文件的单个集合,
  230. * 如果该文件指向一个目录,则返回该目录下的所有文件
  231. *
  232. * @param file
  233. * 可以是目录,也可以是文件,当是文件时,直接返回该文件的列表
  234. * @return 返回该文件夹下的所有子文件
  235. */
  236. public List<File> getSubFile(File file) {
  237. // 文件列表对象
  238. List<File> fileList = new ArrayList<File>();
  239. if (file.isFile()) {
  240. // 如果是普通文件,直接把该文件添加到文件列表
  241. fileList.add(file);
  242. return fileList;
  243. }
  244. if (file.isDirectory()) {
  245. fileList.add(file);
  246. // 如果是目录,则遍历目录下的所有文件
  247. for (File f : file.listFiles()) {
  248. // 这里使用的递归,一直到文件目录的最底层,而文件列表里存的,全是文件
  249. fileList.addAll(getSubFile(f));
  250. }
  251. }
  252. return fileList;
  253. }
  254. }