Java解压Zip文件 小结

悠悠 2022-02-09 11:05 566阅读 0赞

1.首先,列举以下会提及到的三种解压方式:操作7z.exe解压、使用ant-1.9.6.jar解压、使用zip4j-1.3.2.jar解压。

2.第一种:java操作7z.exe解压文件,其实就是通过java内置的类来输入命令操作exe,相关的7z.exe命令详解

1) 打开上面的7z.exe下载链接,打开可以看到7za.exe, 7zxa.dll,copy到项目的tool文件夹下;

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JBU3RyaXZlcg_size_16_color_FFFFFF_t_70

20190502181417238.png

2) 测试类:

  1. package unpack;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. public class 7ZipTool {
  7. private String path;
  8. private final static String defaultPath=".\\tool\\7z.exe";
  9. private final static String[] exts={"rar","zip","7z","tar","tgz","gz","bzip2"};
  10. private final static String wrongPasswordMsg="Wrong password?";
  11. public 7ZipTool(){
  12. this(defaultPath);
  13. }
  14. public 7ZipTool(String path){
  15. this.path=path;
  16. }
  17. public boolean isSupport(File file) {
  18. if(!file.isFile()){
  19. return false;
  20. }
  21. String fileName=file.getAbsolutePath().toLowerCase();
  22. for(int i=0; i<exts.length; i++){
  23. if(fileName.endsWith("."+exts[i])){
  24. return true;
  25. }
  26. }
  27. return false;
  28. }
  29. public void unpack(File source, File target, boolean iter,
  30. boolean isRemove) throws NeosUnpackWrongPasswordException{
  31. if(!target.exists()){
  32. target.mkdirs();
  33. }
  34. if(!target.isDirectory()){
  35. return;
  36. }
  37. if(!iter){
  38. if(isSupport(source)){
  39. unpack(source, target.getAbsolutePath());
  40. if(isRemove){
  41. source.delete();
  42. }
  43. }
  44. }else{
  45. if(source.isDirectory()){
  46. String destPath;
  47. if(!source.equals(target)){
  48. String sourceFileName=source.getName();
  49. destPath=target.getAbsolutePath()+"\\"+sourceFileName;
  50. }else{
  51. destPath=target.getAbsolutePath();
  52. }
  53. File dest=new File(destPath);
  54. File[] children=source.listFiles();
  55. for(int i=0; i<children.length; i++){
  56. unpack(children[i],dest,true,isRemove);
  57. }
  58. }else{
  59. if(isSupport(source)){
  60. unpack(source, target.getAbsolutePath());
  61. if(isRemove){
  62. source.delete();
  63. }
  64. unpack(target, target, true, isRemove);
  65. }
  66. }
  67. }
  68. }
  69. private void unpack(File file, String dest) throws NeosUnpackWrongPasswordException{
  70. String cmd=path+" x \""+file.getAbsolutePath()+"\" -o\""+dest+"\" -p12345 -y";
  71. Runtime rt = Runtime.getRuntime();
  72. try {
  73. Process p = rt.exec(cmd);
  74. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
  75. String s;
  76. boolean isContainEncryptFile=false;
  77. while((s=bufferedReader.readLine()) != null){
  78. if(s.contains(wrongPasswordMsg)){
  79. isContainEncryptFile=true;
  80. continue;
  81. }
  82. }
  83. p.waitFor();
  84. p.destroy();
  85. if(isContainEncryptFile){
  86. throw new NeosUnpackWrongPasswordException(file);
  87. }
  88. } catch (IOException e) {
  89. e.printStackTrace();
  90. } catch(InterruptedException e){
  91. e.printStackTrace();
  92. }
  93. }
  94. public static void main(String[] args) throws NeosUnpackWrongPasswordException {
  95. 7ZipTool tool = new 7ZipTool();
  96. tool.unpack(new File("C:\\Users\\Desktop\\Desktop.Zip"),
  97. new File("C:\\Users\\Desktop"), true, false);
  98. }
  99. }

3.第二种:使用ant-1.9.6.jar。

1) 测试类:

  1. import java.io.File;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.Enumeration;
  6. import org.apache.tools.zip.ZipEntry;
  7. import org.apache.tools.zip.ZipFile;
  8. public class ZipDecompressing {
  9. /**
  10. * @param sourcefiles
  11. * 源文件(服务器上的zip包存放地址)
  12. * @param decompreDirectory
  13. * 解压缩后文件存放的目录
  14. * @throws IOException
  15. * IO异常
  16. */
  17. public static void unzip(String sourcefiles, String decompreDirectory) throws IOException {
  18. ZipFile readfile = null;
  19. try {
  20. readfile = new ZipFile(sourcefiles);
  21. Enumeration<?> takeentrie = readfile.getEntries();
  22. ZipEntry zipEntry = null;
  23. File credirectory = new File(decompreDirectory);
  24. credirectory.mkdirs();
  25. while (takeentrie.hasMoreElements()) {
  26. zipEntry = (ZipEntry) takeentrie.nextElement();
  27. String entryName = zipEntry.getName();
  28. InputStream in = null;
  29. FileOutputStream out = null;
  30. try {
  31. if (zipEntry.isDirectory()) {
  32. String name = zipEntry.getName();
  33. name = name.substring(0, name.length() - 1);
  34. File createDirectory = new File(decompreDirectory + File.separator + name);
  35. createDirectory.mkdirs();
  36. } else {
  37. int index = entryName.lastIndexOf("\\");
  38. if (index != -1) {
  39. File createDirectory = new File(
  40. decompreDirectory + File.separator + entryName.substring(0, index));
  41. createDirectory.mkdirs();
  42. }
  43. index = entryName.lastIndexOf("/");
  44. if (index != -1) {
  45. File createDirectory = new File(
  46. decompreDirectory + File.separator + entryName.substring(0, index));
  47. createDirectory.mkdirs();
  48. }
  49. File unpackfile = new File(decompreDirectory + File.separator + zipEntry.getName());
  50. in = readfile.getInputStream(zipEntry);
  51. out = new FileOutputStream(unpackfile);
  52. int c;
  53. byte[] by = new byte[1024];
  54. while ((c = in.read(by)) != -1) {
  55. out.write(by, 0, c);
  56. }
  57. out.flush();
  58. }
  59. } catch (IOException ex) {
  60. throw new IOException("解压失败:" + ex.toString());
  61. } finally {
  62. if (in != null) {
  63. try {
  64. in.close();
  65. } catch (IOException ex) {
  66. }
  67. }
  68. if (out != null) {
  69. try {
  70. out.close();
  71. } catch (IOException ex) {
  72. }
  73. }
  74. in = null;
  75. out = null;
  76. }
  77. }
  78. } catch (IOException ex) {
  79. throw new IOException("解压失败:" + ex.toString());
  80. } finally {
  81. if (readfile != null) {
  82. try {
  83. readfile.close();
  84. } catch (IOException ex) {
  85. throw new IOException("解压失败:" + ex.toString());
  86. }
  87. }
  88. }
  89. }
  90. public static void main(String[] args) throws IOException {
  91. ZipDecompressing.unzip("C:\\Users\\Downloads\\1324.zip",
  92. "D:\\workplace\\tool");
  93. }
  94. }

4.第三种:使用zip4j-1.3.2.jar。

1) 测试类:

  1. package test;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.util.ArrayList;
  7. import java.util.Enumeration;
  8. import java.util.List;
  9. import java.util.concurrent.ExecutorService;
  10. import java.util.concurrent.Executors;
  11. import org.junit.Test;
  12. import net.lingala.zip4j.core.ZipFile;
  13. import net.lingala.zip4j.exception.ZipException;
  14. public class Zip4j_test {
  15. private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  16. private static String CHARSET = "GBK"; // 文件名编码
  17. private static boolean IS_LOOP = true; // 是否解压子目录的压缩包
  18. private static boolean IS_REMOVE = false; // 是否删除源文件
  19. private static String FILETYPE = "zip"; // 压缩包扩展名
  20. /**
  21. * 解压文件
  22. * @param sourceFilePath 源文件路径
  23. * @param destDirectory 解压路径
  24. * @param password 压缩包密码
  25. * @param FileNameCharset 文件编码
  26. * @param isLoop 是否解压子目录的压缩包
  27. * @param isRemove 是否删除源文件
  28. */
  29. public static void unpack(String sourceFilePath, String destDirectory, String password,
  30. String FileNameCharset, boolean isLoop, boolean isRemove) {
  31. cachedThreadPool.execute(new Runnable() {
  32. public void run() {
  33. // System.out.println("--> 线程: " + Thread.currentThread().getName());
  34. ZipFile zipFile;
  35. try {
  36. zipFile = new ZipFile(sourceFilePath);
  37. if (zipFile.isEncrypted() && password != null) {
  38. zipFile.setPassword(password);
  39. }
  40. zipFile.setFileNameCharset(FileNameCharset); // 设置文件名编码
  41. if (!zipFile.isValidZipFile()) {
  42. // 验证.zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等
  43. throw new ZipException("zip file is invalid.");
  44. }
  45. File destDir = new File(destDirectory); // 解压目录
  46. if (destDir.isDirectory() && !destDir.exists()) {
  47. destDir.mkdir();
  48. }
  49. System.out.println("--> 解压: " + sourceFilePath + " 到: " +destDirectory);
  50. zipFile.extractAll(destDirectory);
  51. List<File> filelist = getFileList(destDirectory, FILETYPE);
  52. System.out.println("--> size: " + filelist.size());
  53. // if( isLoop || (hasZip(filelist) && !isLoop) ) {
  54. if( isLoop && hasZip(filelist) ) {
  55. System.out.println("---> 遍历子压缩包 : "+ filelist.size());
  56. for(File file: filelist) {
  57. // System.out.println(file.getAbsolutePath());
  58. // System.out.println(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")));
  59. unpack(file.getAbsolutePath(),
  60. file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")));
  61. }
  62. }
  63. } catch (ZipException e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. });
  68. }
  69. // 解压到destDirectory目标目录,压缩包附带密码
  70. public static void unpack(String sourceFilePath, String destDirectory, String password) {
  71. unpack(sourceFilePath, destDirectory, password, CHARSET, IS_LOOP, IS_REMOVE);
  72. }
  73. // 解压到destDirectory目标目录,压缩包附带密码
  74. public static void unpack(String sourceFilePath, String destDirectory, String password, String FileNameCharset) {
  75. unpack(sourceFilePath, destDirectory, password, FileNameCharset, IS_LOOP, IS_REMOVE);
  76. }
  77. // 解压到destDirectory目标目录,是否解压子目录的压缩包
  78. public static void unpack(String sourceFilePath, String destDirectory, boolean isLoop) {
  79. // if(!isLoop)
  80. // unzip(sourceFilePath, destDirectory);
  81. // else
  82. unpack(sourceFilePath, destDirectory, null, CHARSET, isLoop, IS_REMOVE);
  83. }
  84. // 解压到destDirectory目标目录
  85. public static void unpack(String sourceFilePath, String destDirectory) {
  86. // unzip(sourceFilePath, destDirectory);
  87. if(destDirectory != null)
  88. unpack(sourceFilePath, destDirectory, null, CHARSET, IS_LOOP, IS_REMOVE);
  89. else
  90. unpack(sourceFilePath);
  91. }
  92. // 解压到当前目录
  93. public static void unpack(String sourceFilePath) {
  94. unpack(sourceFilePath, new File(sourceFilePath).getParentFile().getAbsolutePath());
  95. }
  96. //
  97. public static void unzip(String sourcefiles, String decompreDirectory) {
  98. org.apache.tools.zip.ZipFile readfile = null;
  99. try {
  100. readfile = new org.apache.tools.zip.ZipFile(sourcefiles);
  101. Enumeration<?> takeentrie = readfile.getEntries();
  102. org.apache.tools.zip.ZipEntry zipEntry = null;
  103. File credirectory = new File(decompreDirectory);
  104. credirectory.mkdirs();
  105. while (takeentrie.hasMoreElements()) {
  106. zipEntry = (org.apache.tools.zip.ZipEntry) takeentrie.nextElement();
  107. String entryName = zipEntry.getName();
  108. InputStream in = null;
  109. FileOutputStream out = null;
  110. try {
  111. if (zipEntry.isDirectory()) {
  112. String name = zipEntry.getName();
  113. name = name.substring(0, name.length() - 1);
  114. File createDirectory = new File(decompreDirectory + File.separator + name);
  115. createDirectory.mkdirs();
  116. } else {
  117. int index = entryName.lastIndexOf("\\");
  118. if (index != -1) {
  119. File createDirectory = new File(
  120. decompreDirectory + File.separator + entryName.substring(0, index));
  121. createDirectory.mkdirs();
  122. }
  123. index = entryName.lastIndexOf("/");
  124. if (index != -1) {
  125. File createDirectory = new File(
  126. decompreDirectory + File.separator + entryName.substring(0, index));
  127. createDirectory.mkdirs();
  128. }
  129. File unpackfile = new File(decompreDirectory + File.separator + zipEntry.getName());
  130. in = readfile.getInputStream(zipEntry);
  131. out = new FileOutputStream(unpackfile);
  132. int c;
  133. byte[] by = new byte[1024];
  134. while ((c = in.read(by)) != -1) {
  135. out.write(by, 0, c);
  136. }
  137. out.flush();
  138. }
  139. } catch (IOException ex) {
  140. throw new IOException("解压失败:" + ex.toString());
  141. } finally {
  142. if (in != null) {
  143. try {
  144. in.close();
  145. } catch (IOException ex) {
  146. }
  147. }
  148. if (out != null) {
  149. try {
  150. out.close();
  151. } catch (IOException ex) {
  152. }
  153. }
  154. in = null;
  155. out = null;
  156. }
  157. }
  158. } catch (IOException ex) {
  159. ex.printStackTrace();
  160. } finally {
  161. if (readfile != null) {
  162. try {
  163. readfile.close();
  164. } catch (IOException ex) {
  165. ex.printStackTrace();
  166. }
  167. }
  168. }
  169. }
  170. /**
  171. * 判断目录下是否有压缩包
  172. * @param fileList
  173. * @return
  174. */
  175. public static boolean hasZip(List<File> fileList) {
  176. for (File file: fileList) {
  177. if(file.getName().toLowerCase().endsWith(FILETYPE.toLowerCase()))
  178. return true;
  179. }
  180. return false;
  181. }
  182. /**
  183. * 获取目录下后缀名为endwith的文件
  184. * @param strPath 文件夹路径
  185. * @param endwith 后缀名
  186. * @return
  187. */
  188. public static List<File> getFileList(String strPath, String endwith) {
  189. List<File> filelist = new ArrayList<>();
  190. File dir = new File(strPath);
  191. File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
  192. if (files != null) {
  193. for (int i = 0; i < files.length; i++) {
  194. String fileName = files[i].getName();
  195. if (files[i].isDirectory()) { // 判断是文件还是文件夹
  196. System.out.println("---> 文件夹:" + files[i].getName());
  197. return getFileList(files[i].getAbsolutePath(), endwith); // 获取文件绝对路径
  198. } else if (fileName.toLowerCase().endsWith(endwith.toLowerCase())) { // 判断文件名是否以.xml结尾
  199. String strFileName = files[i].getAbsolutePath();
  200. System.out.println("---> 文件:" + files[i].getName());
  201. filelist.add(files[i]);
  202. } else {
  203. System.out.println("---> 不处理:"+files[i].getName());
  204. continue;
  205. }
  206. }
  207. }
  208. else
  209. System.out.println("文件夹为空");
  210. return filelist;
  211. }
  212. public static void main(String[] args) {
  213. try {
  214. ZipFile zipFile = new ZipFile("D:\\workplace\\zip\\abc.zip");
  215. if (zipFile.isEncrypted()) {
  216. // if yes, then set the password for the zip file
  217. zipFile.setPassword("1234");
  218. }
  219. zipFile.setFileNameCharset("GBK"); // 设置文件名编码,在GBK系统中需要设置
  220. if (!zipFile.isValidZipFile()) { // 验证.zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等
  221. throw new ZipException("压缩文件不合法,可能被损坏.");
  222. }
  223. File destDir = new File("D:\\workplace"); // 解压目录
  224. if (destDir.isDirectory() && !destDir.exists()) {
  225. destDir.mkdir();
  226. }
  227. zipFile.extractAll("D:\\workplace");
  228. /*
  229. List fileHeaderList = zipFile.getFileHeaders();
  230. for (int i = 0; i < fileHeaderList.size(); i++) {
  231. FileHeader fileHeader = (FileHeader)fileHeaderList.get(i);
  232. zipFile.extractFile(fileHeader, "D:\\workplace");
  233. }
  234. */
  235. } catch (ZipException e) {
  236. e.printStackTrace();
  237. }
  238. }
  239. @Test
  240. public void pubic() throws InterruptedException {
  241. // TODO Auto-generated method stub
  242. Zip4j_test.unpack("D:\\workplace\\zip\\abc.Zip",
  243. "D:\\workplace\\test",
  244. "1234");
  245. Thread.sleep(60000);
  246. }
  247. }

部分参考:

1.https://snowolf.iteye.com/blog/643010

2.https://blog.csdn.net/educast/article/details/38755287

注:

  1. 有时候gz文件不一定是valid的,所以可能会遇到:Java java.io.IOException: Not in GZIP format

发表评论

表情:
评论列表 (有 0 条评论,566人围观)

还没有评论,来说两句吧...

相关阅读