View Javadoc
1   package net.sumaris.core.util;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Core Shared
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  
28  import org.apache.commons.io.IOUtils;
29  import org.springframework.util.StreamUtils;
30  
31  import java.io.*;
32  import java.util.Enumeration;
33  import java.util.Objects;
34  import java.util.zip.ZipEntry;
35  import java.util.zip.ZipFile;
36  import java.util.zip.ZipOutputStream;
37  
38  /**
39   * <p>ZipUtils class.</p>
40   */
41  public class ZipUtils {
42  
43      /**
44       * <p>Constructor for ZipUtils.</p>
45       */
46      protected ZipUtils() {
47          // helper class
48      }
49  
50      /**
51       * <p>compressFilesInPath.</p>
52       *
53       * @param path a {@link String} object.
54       * @param compressedFile a {@link File} object.
55       * @param deleteAfterCompress a boolean.
56       * @throws IOException if any.
57       */
58      public static void compressFilesInPath(String path, File compressedFile, boolean deleteAfterCompress) throws IOException {
59          compressFilesInPath(new File(path), compressedFile, deleteAfterCompress);
60      }
61  
62      /**
63       * <p>compressFilesInPath.</p>
64       *
65       * @param fileSource a {@link File} object.
66       * @param compressedFile a {@link File} object.
67       * @param deleteAfterCompress a boolean.
68       * @throws IOException if any.
69       */
70      public static void compressFilesInPath(File fileSource, File compressedFile, boolean deleteAfterCompress) throws IOException {
71          ZipOutputStream zout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(compressedFile)));
72          compressDirectory(fileSource, fileSource, compressedFile, zout, deleteAfterCompress);
73          zout.close();
74      }
75  
76  
77      /**
78       * <p>uncompressFileToPath.</p>
79       *
80       * @param compressedFile a {@link File} object.
81       * @param path a {@link String} object.
82       * @param deleteAfterUncompress a boolean.
83       * @throws IOException if any.
84       */
85      public static void uncompressFileToPath(File compressedFile, String path, boolean deleteAfterUncompress) throws IOException {
86          File destDir;
87          if (path != null) {
88              destDir = new File(path);
89          }
90          else {
91              destDir = new File(compressedFile.getParent());
92          }
93          destDir.mkdirs();
94  
95          ZipFile zipFile = new ZipFile(compressedFile);
96          Enumeration<? extends ZipEntry> entries = zipFile.entries();
97          while (entries.hasMoreElements()) {
98              ZipEntry zipEntry = entries.nextElement();
99              if (!zipEntry.isDirectory()) {
100                 File destFile = new File(destDir, zipEntry.getName());
101                 destFile.getParentFile().mkdirs();
102                 OutputStream out = new BufferedOutputStream(new FileOutputStream(destFile));
103                 StreamUtils.copy(zipFile.getInputStream(zipEntry), out);
104                 out.flush();
105                 out.close();
106             }
107         }
108         zipFile.close();
109         if (deleteAfterUncompress) {
110             compressedFile.delete();
111         }
112     }
113 
114     /* -- Internal methods -- */
115 
116 
117     private static void compressDirectory(File rootFileSource, File fileSource, File compressedFile, ZipOutputStream zout, boolean deleteAfterCompress) throws IOException {
118         File[] files = fileSource.listFiles();
119         for (File file : Objects.requireNonNull(files)) {
120             if (file.equals(compressedFile)) {
121                 continue;
122             }
123             if (file.isDirectory()) {
124                 String zipEntryName = toZipEntryName(rootFileSource, file);
125                 zout.putNextEntry(new ZipEntry(zipEntryName));
126                 compressDirectory(rootFileSource, file, compressedFile, zout, deleteAfterCompress);
127                 zout.closeEntry();
128                 if (deleteAfterCompress) {
129                     file.delete();
130                 }
131                 continue;
132             }
133             InputStream in = new BufferedInputStream(new FileInputStream(file));
134             String zipEntryName = toZipEntryName(rootFileSource, file);
135             zout.putNextEntry(new ZipEntry(zipEntryName));
136             IOUtils.copy(in, zout);
137             zout.closeEntry();
138             in.close();
139             if (deleteAfterCompress) {
140                 file.delete();
141             }
142         }
143     }
144 
145     private static String toZipEntryName(File root, File file) {
146         String result = file.getPath();
147         if(root != null) {
148             String rootPath = root.getPath();
149             if(result.startsWith(rootPath)) {
150                 result = result.substring(rootPath.length());
151             }
152         }
153 
154         result = result.replace('\\', '/');
155         if(file.isDirectory()) {
156             result = result + '/';
157         }
158 
159         while(result.startsWith("/")) {
160             result = result.substring(1);
161         }
162 
163         return result;
164     }
165 }