View Javadoc

1   package pl.psnc.dl.ege.utils;
2   
3   import java.io.BufferedInputStream;
4   import java.io.BufferedOutputStream;
5   import java.io.File;
6   import java.io.FileInputStream;
7   import java.io.FileNotFoundException;
8   import java.io.FileOutputStream;
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.OutputStream;
12  import java.util.Enumeration;
13  import java.util.zip.ZipEntry;
14  import java.util.zip.ZipFile;
15  import java.util.zip.ZipInputStream;
16  import java.util.zip.ZipOutputStream;
17  
18  import org.apache.log4j.Logger;
19  
20  /**
21   * Pack of usable EGE IO utilities.
22   * 
23   * TODO : switch to external IO Utilities (e.g. from Vesta or Apache Commons)
24   * 
25   * @author mariuszs
26   */
27  public final class EGEIOUtils {
28  
29  	private static final Logger LOGGER = Logger.getLogger(EGEIOUtils.class);
30  
31  	private EGEIOUtils() {
32  	}
33  
34  	private static final int BUFFER = 2048;
35  
36  	/**
37  	 * Construct zip file from specified dir location. Result is transfered into
38  	 * ZipOutputStream.
39  	 * 
40  	 * @param file
41  	 *            directory to pack
42  	 * @param out
43  	 *            zip output stream
44  	 * @param dir
45  	 *            used for zip entries
46  	 * @throws IOException
47  	 */
48  	public static void constructZip(File file, ZipOutputStream out, String dir)
49  			throws IOException {
50  		BufferedInputStream origin = null;
51  		FileInputStream fi = null;
52  
53  		byte data[] = new byte[BUFFER];
54  
55  		File[] files = file.listFiles();
56  
57  		for (int i = 0; i < files.length; i++) {
58  			if (files[i].isDirectory()) {
59  				constructZip(files[i], out, dir + files[i].getName() + "/");
60  				continue;
61  			}
62  
63  			// read file
64  			try {
65  				fi = new FileInputStream(files[i]);
66  				origin = new BufferedInputStream(fi, BUFFER);
67  
68  				// create zip entry
69  				ZipEntry entry = new ZipEntry(dir + files[i].getName());
70  
71  				// add entries to ZIP file
72  				out.putNextEntry(entry);
73  
74  				// write data
75  				int count;
76  				while ((count = origin.read(data, 0, BUFFER)) != -1) {
77  					out.write(data, 0, count);
78  				}
79  			} finally {
80  				if (fi != null) {
81  					try {
82  						fi.close();
83  					} catch (IOException ex) {
84  						// do nothing
85  					}
86  				}
87  				if (origin != null) {
88  					try {
89  						origin.close();
90  					} catch (IOException ex) {
91  						LOGGER.error(ex.getMessage());
92  					}
93  				}
94  			}
95  			// close
96  
97  		}
98  	}
99  
100 	/**
101 	 * Deletes a directory.
102 	 * 
103 	 * @param dir
104 	 *            The directory to delete
105 	 * @return Returns true on success.
106 	 */
107 	public static boolean deleteDirectory(File dir) {
108 		if (dir.isDirectory())
109 			for (String child : dir.list())
110 				if (!deleteDirectory(new File(dir, child))) {
111 					return false;
112 				}
113 		return dir.delete();
114 	}
115 
116 	/**
117 	 * Perform copy from input stream to output stream.
118 	 * 
119 	 * @param is
120 	 *            source stream
121 	 * @param os
122 	 *            result stream
123 	 * @throws IOException
124 	 */
125 	public static void copyStream(InputStream is, OutputStream os)
126 			throws IOException {
127 		byte[] buffer = new byte[131072];
128 		int bytesRead;
129 
130 		while ((bytesRead = is.read(buffer)) > 0) {
131 			os.write(buffer, 0, bytesRead);
132 		}
133 	}
134 
135 	/**
136 	 * Extracts content of the zipFile to given destination directory
137 	 * 
138 	 * @param zipFile
139 	 *            the file to unzip
140 	 * @param destinationDir
141 	 *            destination directory for the content of the zipFile
142 	 * @throws FileNotFoundException
143 	 *             if a file could not be created
144 	 * @throws IOException
145 	 *             if IO error occurs
146 	 */
147 	public static void unzipFile(ZipFile zipFile, File destinationDir)
148 			throws FileNotFoundException, IOException {
149 
150 		if (!destinationDir.exists()) {
151 			destinationDir.mkdirs();
152 		}
153 
154 		Enumeration<? extends ZipEntry> entries = zipFile.entries();
155 		while (entries.hasMoreElements()) {
156 			ZipEntry entry = entries.nextElement();
157 			if (!entry.isDirectory()) {
158 
159 				File file = new File(destinationDir, entry.getName());
160 				File parentFile = file.getParentFile();
161 				if (parentFile != null) {
162 					parentFile.mkdirs();
163 				}
164 				InputStream inputStream = zipFile.getInputStream(entry);
165 				FileOutputStream outputStream = new FileOutputStream(file);
166 
167 				try {
168 					copyStream(inputStream, outputStream);
169 				} finally {
170 					inputStream.close();
171 					outputStream.close();
172 				}
173 			}
174 		}
175 	}
176 
177 	/**
178 	 * Unzips a zip compressed file to some output directory.
179 	 * 
180 	 * @param in
181 	 *            The InputStream.
182 	 * @param outputDir
183 	 *            The output directory.
184 	 * @throws IOException
185 	 * @throws FileNotFoundException
186 	 */
187 	public static void unzipStream(InputStream in, File outputDir)
188 			throws FileNotFoundException, IOException {
189 		// name of the directory
190 		String directoryName = outputDir.getAbsolutePath();
191 
192 		// buffer
193 		int BUFFER = 2048;
194 		// output
195 		BufferedOutputStream dest;
196 
197 		// create tmp directory
198 		if (!outputDir.isDirectory())
199 			outputDir.mkdirs();
200 
201 		// read file
202 		ZipInputStream zis = new ZipInputStream(new BufferedInputStream(in));
203 
204 		// decompress file
205 		ZipEntry entry;
206 		while ((entry = zis.getNextEntry()) != null) {
207 			// if it is a directory, create it
208 			if (entry.isDirectory()) {
209 				File dir = new File(directoryName + File.separator
210 						+ entry.getName());
211 				if (!dir.exists())
212 					dir.mkdirs();
213 				continue;
214 			}
215 
216 			// create directories if necessary
217 			new File(new File(directoryName + File.separator + entry.getName())
218 					.getParent()).mkdirs();
219 
220 			int count;
221 			byte data[] = new byte[BUFFER];
222 			// write the files to the disk
223 			FileOutputStream fos = new FileOutputStream(directoryName
224 					+ File.separator + entry.getName());
225 			dest = new BufferedOutputStream(fos, BUFFER);
226 			while ((count = zis.read(data, 0, BUFFER)) != -1) {
227 				dest.write(data, 0, count);
228 			}
229 			dest.flush();
230 			dest.close();
231 		}
232 
233 	}
234 
235 	/**
236 	 * Checks if specified zip content contains more than one file.
237 	 * 
238 	 * @param zipFile
239 	 * @return
240 	 * @throws IOException
241 	 */
242 	public static boolean isComplexZip(File zipFile) throws IOException {
243 
244 		ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
245 		try {
246 			int count = 0;
247 			ZipEntry zipEntry = null;
248 			while ((zipEntry = zis.getNextEntry()) != null) {
249 				if (!zipEntry.isDirectory()) {
250 					count++;
251 				}
252 				if (count > 1) {
253 					return true;
254 				}
255 			}
256 			return false;
257 
258 		} finally {
259 			zis.close();
260 		}
261 	}
262 
263 	/**
264 	 * Unpacks single file data to stream. Should be only used when expecting
265 	 * single file in zip package.
266 	 * 
267 	 * @param zipFile
268 	 * @param os
269 	 */
270 	public static void unzipSingleFile(ZipFile zipFile, OutputStream os)
271 			throws IOException {
272 		try {
273 			Enumeration<? extends ZipEntry> entries = zipFile.entries();
274 			while (entries.hasMoreElements()) {
275 				ZipEntry entry = entries.nextElement();
276 				if (!entry.isDirectory()) {
277 					InputStream is = zipFile.getInputStream(entry);
278 					try{
279 						copyStream(is, os);
280 					}finally{
281 						is.close();
282 					}
283 					return;
284 				}
285 			}
286 		} finally {
287 			zipFile.close();
288 		}
289 	}
290 
291 }