1 /********************************************************************************
2 *InternetCafe is a software solution that helps the management of Cybercafes
3 * according with the ITALIAN DECREE LAW ON ANTI-TERROR MEASURES, 27 JULY 2005.
4 * Copyright (C) 2006 Guido Angelo Ingenito
5
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *******************************************************************************/
20 package base.util;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.security.MessageDigest;
28 import java.security.NoSuchAlgorithmException;
29 import java.util.Vector;
30 import java.util.zip.CRC32;
31
32 import org.apache.log4j.Logger;
33 import org.bouncycastle.util.encoders.Hex;
34
35 /***
36 * This class provides some basic methods to manage files and folders.
37 *
38 * @author Guido Angelo Ingenito
39 */
40 public class FileUtil {
41
42 private static final transient Logger logger = Logger
43 .getLogger(FileUtil.class.getName());
44
45 /***
46 * This method computes the specified file occupied space on the HD. If the
47 * input file is a simple file will be returned its size otherwise if the
48 * file is a directory on local HD will be recursivelly computed the
49 * occupied space of subfolders and contained files.
50 *
51 * @param file
52 * The file or directory whose size must be computed.
53 * @return A Byte rappresentation of the file'size.
54 */
55 public static long fileSizeInByte(File file) {
56 long size = 0;
57
58 if (file.isDirectory()) {
59 File[] filelist = file.listFiles();
60 for (int i = 0; i < filelist.length; i++) {
61 if (filelist[i].isDirectory()) {
62 size += fileSizeInByte(filelist[i]);
63 } else {
64 size += filelist[i].length();
65 }
66 }
67 } else
68 size += file.length();
69
70 return size;
71 }
72
73 /***
74 * This method computes the specified file occupied space on the HD. If the
75 * input file is a simple file will be returned its size otherwise if the
76 * file is a directory on local HD will be recursivelly computed the
77 * occupied space of subfolders and contained files.
78 *
79 * @param file
80 * The file or directory whose size must be computed.
81 * @return A Kylo Byte rappresentation of the file'size.
82 */
83 public static long fileSizeInKB(File file) {
84 return fileSizeInByte(file) / 1024;
85 }
86
87 /***
88 * This method computes the specified file occupied space on the HD. If the
89 * input file is a simple file will be returned its size otherwise if the
90 * file is a directory on local HD will be recursivelly computed the
91 * occupied space of subfolders and contained files.
92 *
93 * @param file
94 * The file or directory whose size must be computed.
95 * @return A Mega Byte rappresentation of the file'size.
96 */
97 public static long fileSizeInMB(File file) {
98 return fileSizeInByte(file) / 1048576;
99 }
100
101 /***
102 * This method computes the specified file occupied space on the HD. If the
103 * input file is a simple file will be returned its size otherwise if the
104 * file is a directory on local HD will be recursivelly computed the
105 * occupied space of subfolders and contained files.
106 *
107 * @param file
108 * The file or directory whose size must be computed.
109 * @return A Giga Byte rappresentation of the file'size.
110 */
111 public static long fileSizeInGB(File file) {
112 return fileSizeInByte(file) / 1073741824;
113 }
114
115 /***
116 * This method creates a CRC32 Checksum relative to the file passed as
117 * formal parameter.
118 *
119 * @param file
120 * The file whose checksum must be created.
121 * @return The value of the CRC32 checksum-
122 * @throws IOException
123 * If can't be created the InputStream associated to the input
124 * File.
125 */
126 public static Long createCRC32Checksum(File file) throws IOException {
127 logger.debug("createCRC32Checksum(" + file.toString() + ")");
128
129 InputStream inputStream = new FileInputStream(file);
130 CRC32 checksum = new CRC32();
131 checksum.reset();
132 byte[] buffer = new byte[1024];
133 int bytesRead;
134 while ((bytesRead = inputStream.read(buffer)) >= 0) {
135 checksum.update(buffer, 0, bytesRead);
136 }
137 inputStream.close();
138 logger.debug("CRC32 Checksum value: " + checksum.getValue());
139
140 return new Long(checksum.getValue());
141 }
142
143 /***
144 * This method checks if the computed CRC32 Checksum of the input file is
145 * equals to the provided crc32Checksum passed as formal argument.
146 *
147 * @param file
148 * The file whose checksum must be compared with the input
149 * crc32Checksum.
150 * @param crc32Checksum
151 * The comparation parameter.
152 * @return True if the computed checksum is queals to the crc32Checksum,
153 * false otherwise.
154 * @throws IOException
155 * If can't be created the InputStream associated to the input
156 * File.
157 */
158 public static boolean checkCRC32Checksum(File file, Long crc32Checksum)
159 throws IOException {
160 logger.debug("checkCRC32Checksum(" + file.toString() + ","
161 + crc32Checksum + ")");
162 Long checksum = createCRC32Checksum(file);
163 return checksum.equals(crc32Checksum);
164 }
165
166 /***
167 * This method builds an array of files. In the case the passed formal
168 * parameter named "file" is a simple file it is returned otherwise if it is
169 * a directory all sub-files and sub-directories are navigated recursivelly
170 * and are added to the resultant array.
171 *
172 * @param file
173 * The file or folder from which the resultant array is built.
174 * @return An array of one file if the formal parameter named "file" is a
175 * simple file a list of sub-files or sub-directories built
176 * recursivelly if the formal parameter is a directory.
177 */
178 public static File[] allFileContent(File file) {
179 Vector<File> result = new Vector<File>();
180
181 if (file.isDirectory()) {
182 File[] filelist = file.listFiles();
183 for (int i = 0; i < filelist.length; i++) {
184 if (filelist[i].isDirectory()) {
185 File[] content = allFileContent(filelist[i]);
186 for (int k = 0; k < content.length; k++)
187 result.add(content[k]);
188 } else {
189 result.add(filelist[i]);
190 }
191 }
192 } else
193 result.add(file);
194
195 return result.toArray(new File[0]);
196 }
197
198 /***
199 * Deletes all files and subdirectories under directory.
200 *
201 * @param directory
202 * The directory that must be deleted.
203 * @return True if all deletions were successful. If a deletion fails, the
204 * method stops attempting to delete and returns false.
205 */
206 public static boolean deleteDirectory(File directory) {
207 if (directory.isDirectory()) {
208 String[] children = directory.list();
209 for (int i = 0; i < children.length; i++) {
210 File toBeDeleted = new File(directory, children[i]);
211 logger.debug("Deleting : " + toBeDeleted);
212 boolean success = deleteDirectory(toBeDeleted);
213 if (!success) {
214 return false;
215 }
216 }
217 }
218
219 return directory.delete();
220 }
221
222 /***
223 * This method builds an MD5 Digest of a provided input file.
224 *
225 * @param file
226 * The file whose MD5 Digest must be build.
227 * @return The files'MD5 Digest.
228 * @throws IOException
229 * If the method can't use the filesystem or the provided file
230 * doesn't exists.
231 */
232 public static String createMD5Digest(File file) throws IOException {
233 String result = "";
234 InputStream inputStream = new FileInputStream(file);
235 MessageDigest messageDigest;
236 try {
237 messageDigest = MessageDigest.getInstance("MD5");
238
239 byte[] buffer = new byte[1024];
240 int bytesRead;
241 while ((bytesRead = inputStream.read(buffer)) >= 0) {
242 messageDigest.update(buffer, 0, bytesRead);
243 }
244 inputStream.close();
245 result = new String(Hex.encode(messageDigest.digest()));
246
247 logger.debug("The MD5 Digest for: " + file + " is: " + result);
248
249 } catch (NoSuchAlgorithmException ex) {
250
251 logger.error(ex.getMessage());
252 ex.printStackTrace();
253 }
254 return result;
255 }
256
257 /***
258 * This method checks if the computed MD5 Digest of the input file is equals
259 * to the provided md5Digest passed as formal argument.
260 *
261 * @param file
262 * The file whose md5 digest must be compared with the input
263 * md5Digest.
264 * @param md5Digest
265 * The comparation parameter.
266 * @return True if the computed md5 digest is queals to the md5Digest, false
267 * otherwise.
268 * @throws IOException
269 * If can't be created the InputStream associated to the input
270 * File.
271 */
272 public static boolean checkMD5Digest(File file, String md5Digest)
273 throws IOException {
274 logger.debug("checkMD5Digest(" + file.toString() + "," + md5Digest
275 + ")");
276 String digest = createMD5Digest(file);
277 return digest.equals(md5Digest);
278 }
279
280 /***
281 * This method reads all the lines of the input file returning its content
282 * in form of a String.
283 *
284 * @param file
285 * The file whose content must be retrieved.
286 * @return The content of the input file.
287 * @throws IOException
288 * If can't work on the filesystem.
289 */
290 public static String fileContent(File file) throws IOException {
291 StringBuffer result = new StringBuffer();
292 FileInputStream inputStream = new FileInputStream(file);
293 byte[] buffer = new byte[1024];
294
295 int numRead = 0;
296 while ((numRead = inputStream.read(buffer)) >= 0) {
297 result.append(new String(buffer).toCharArray(), 0, numRead);
298
299 }
300 return result.toString();
301 }
302
303 public static void copyFile(File input, File output) throws IOException {
304 FileInputStream inputStream = new FileInputStream(input);
305 FileOutputStream outputStream = new FileOutputStream(output);
306 byte[] buffer = new byte[1024];
307
308 int numRead = 0;
309 while ((numRead = inputStream.read(buffer)) >= 0) {
310 outputStream.write(buffer, 0, numRead);
311 }
312 inputStream.close();
313 outputStream.close();
314 }
315 }