1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.file;
21
22 import org.apache.commons.compress.compressors.CompressorInputStream;
23 import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
24 import org.waarp.common.command.exception.Reply550Exception;
25 import org.waarp.common.digest.FilesystemBasedDigest;
26 import org.waarp.common.logging.SysErrLogger;
27
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.FileNotFoundException;
31 import java.io.FileOutputStream;
32 import java.io.FilenameFilter;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.OutputStream;
36 import java.io.RandomAccessFile;
37 import java.io.Reader;
38 import java.io.Writer;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41
42 import static com.google.common.base.Preconditions.*;
43
44
45
46
47 public final class FileUtils {
48 public static final int ZERO_COPY_CHUNK_SIZE = 64 * 1024;
49
50 private static final File[] FILE_0_LENGTH = new File[0];
51
52 private FileUtils() {
53 }
54
55 public static void close(final Reader stream) {
56 if (stream == null) {
57 return;
58 }
59 try {
60 stream.close();
61 } catch (final Exception ignored) {
62 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
63 }
64 }
65
66 public static void close(final Writer stream) {
67 if (stream == null) {
68 return;
69 }
70 try {
71 stream.flush();
72 } catch (final Exception ignored) {
73 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
74 }
75 try {
76 stream.close();
77 } catch (final Exception ignored) {
78 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
79 }
80 }
81
82 public static void close(final InputStream stream) {
83 if (stream == null) {
84 return;
85 }
86 try {
87 stream.close();
88 } catch (final Exception ignored) {
89 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
90 }
91 }
92
93 public static void close(final OutputStream stream) {
94 if (stream == null) {
95 return;
96 }
97 try {
98 stream.flush();
99 } catch (final Exception ignored) {
100 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
101 }
102 try {
103 stream.close();
104 } catch (final Exception ignored) {
105 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
106 }
107 }
108
109 public static void close(final RandomAccessFile accessFile) {
110 if (accessFile == null) {
111 return;
112 }
113 try {
114 accessFile.close();
115 } catch (final Exception ignored) {
116 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
117 }
118 }
119
120
121
122
123
124
125
126
127 public static boolean deleteDir(final File directory) {
128 if (directory == null) {
129 return true;
130 }
131 if (!directory.exists()) {
132 return true;
133 }
134 if (!directory.isDirectory()) {
135 return false;
136 }
137 return directory.delete();
138 }
139
140
141
142
143
144
145
146
147 public static boolean delete(final File file) {
148 if (!file.exists()) {
149 return true;
150 }
151 return file.delete();
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165
166 public static File[] copyRecursive(final File from, final File directoryTo,
167 final boolean move)
168 throws Reply550Exception {
169 if (from == null || directoryTo == null) {
170 return null;
171 }
172 final ArrayList<File> to = new ArrayList<File>();
173 if (createDir(directoryTo)) {
174 final File[] subfrom = from.listFiles();
175 if (subfrom != null) {
176 for (final File element : subfrom) {
177 if (element.isFile()) {
178 to.add(copyToDir(element, directoryTo, move));
179 } else {
180 final File newTo = new File(directoryTo, element.getName());
181 newTo.mkdirs();
182 final File[] copied = copyRecursive(element, newTo, move);
183 to.addAll(Arrays.asList(copied));
184 }
185 }
186 }
187 }
188 return to.toArray(FILE_0_LENGTH);
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203 public static File[] copy(final File[] from, final File directoryTo,
204 final boolean move) throws Reply550Exception {
205 if (from == null || directoryTo == null) {
206 return null;
207 }
208 File[] to = null;
209 if (createDir(directoryTo)) {
210 to = new File[from.length];
211 for (int i = 0; i < from.length; i++) {
212 if (from[i].isFile()) {
213 to[i] = copyToDir(from[i], directoryTo, move);
214 }
215 }
216 }
217 return to;
218 }
219
220
221
222
223
224
225
226
227 public static boolean createDir(final File directory) {
228 if (directory == null) {
229 return false;
230 }
231 if (directory.isDirectory()) {
232 return true;
233 }
234 return directory.mkdirs();
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248 private static File copyToDir(final File from, final File directoryTo,
249 final boolean move) throws Reply550Exception {
250 if (from == null || directoryTo == null) {
251 throw new Reply550Exception("Source or Destination is null");
252 }
253 if (!from.isFile()) {
254 throw new Reply550Exception("Source file is a directory");
255 }
256 if (createDir(directoryTo)) {
257 final File to = new File(directoryTo, from.getName());
258 copy(from, to, move, false);
259 return to;
260 }
261 throw new Reply550Exception("Cannot access to parent dir of destination");
262 }
263
264
265
266
267
268
269
270
271
272
273
274 public static void copy(final File from, final File to, final boolean move,
275 final boolean append) throws Reply550Exception {
276 if (from == null || to == null) {
277 throw new Reply550Exception("Source or Destination is null");
278 }
279 if (!from.isFile()) {
280 throw new Reply550Exception("Source file is a directory");
281 }
282 final File directoryTo = to.getParentFile();
283 if (createDir(directoryTo)) {
284 if (move && from.renameTo(to)) {
285 return;
286 }
287 FileInputStream inputStream = null;
288 FileOutputStream outputStream = null;
289 try {
290 try {
291 inputStream = new FileInputStream(from.getPath());
292 } catch (final FileNotFoundException e) {
293 throw new Reply550Exception("Cannot read source file");
294 }
295 try {
296 outputStream = new FileOutputStream(to.getPath(), append);
297 } catch (final FileNotFoundException e) {
298 throw new Reply550Exception("Cannot write destination file");
299 }
300 try {
301 copy(inputStream, outputStream);
302 } catch (final IOException e) {
303 throw new Reply550Exception("Cannot copy, e");
304 }
305 } finally {
306 close(outputStream);
307 close(inputStream);
308 }
309 if (move) {
310
311 from.delete();
312 }
313 return;
314 }
315 throw new Reply550Exception("Cannot access to parent dir of destination");
316 }
317
318
319
320
321
322
323
324
325
326 private static boolean deleteRecursiveFileDir(final File dir) {
327 if (dir == null) {
328 return true;
329 }
330 boolean retour = true;
331 if (!dir.exists()) {
332 return true;
333 }
334 final File[] list = dir.listFiles();
335 if (list == null || list.length == 0) {
336 return dir.delete();
337 }
338 for (final File file : list) {
339 if (file.isDirectory()) {
340 if (!deleteRecursiveFileDir(file)) {
341 retour = false;
342 }
343 } else {
344 return false;
345 }
346 }
347 if (retour) {
348 retour = dir.delete();
349 }
350 return retour;
351 }
352
353
354
355
356
357
358
359
360 private static boolean forceDeleteRecursiveSubDir(final File directory) {
361 if (directory == null) {
362 return true;
363 }
364 boolean retour = true;
365 if (!directory.exists()) {
366 return true;
367 }
368 if (!directory.isDirectory()) {
369 return directory.delete();
370 }
371 final File[] list = directory.listFiles();
372 if (list == null || list.length == 0) {
373 return true;
374 }
375 for (final File file : list) {
376 if (file.isDirectory()) {
377 if (!forceDeleteRecursiveSubDir(file)) {
378 retour = false;
379 }
380 } else {
381 if (!file.delete()) {
382 retour = false;
383 }
384 }
385 }
386 if (retour) {
387 retour = directory.delete();
388 }
389 return retour;
390 }
391
392
393
394
395
396
397
398
399 public static boolean forceDeleteRecursiveDir(final File directory) {
400 if (directory == null) {
401 return true;
402 }
403 boolean retour = true;
404 if (!directory.exists()) {
405 return true;
406 }
407 if (!directory.isDirectory()) {
408 return false;
409 }
410 final File[] list = directory.listFiles();
411 if (list == null || list.length == 0) {
412 return true;
413 }
414 for (final File file : list) {
415 if (file.isDirectory()) {
416 if (!forceDeleteRecursiveSubDir(file)) {
417 retour = false;
418 }
419 } else {
420 if (!file.delete()) {
421 retour = false;
422 }
423 }
424 }
425 return retour;
426 }
427
428
429
430
431
432
433
434
435
436 public static boolean deleteRecursiveDir(final File directory) {
437 if (directory == null) {
438 return true;
439 }
440 boolean retour = true;
441 if (!directory.exists()) {
442 return true;
443 }
444 if (!directory.isDirectory()) {
445 return false;
446 }
447 final File[] list = directory.listFiles();
448 if (list == null || list.length == 0) {
449 retour = directory.delete();
450 return retour;
451 }
452 for (final File file : list) {
453 if (file.isDirectory()) {
454 if (!deleteRecursiveFileDir(file)) {
455 retour = false;
456 }
457 } else {
458 retour = false;
459 }
460 }
461 if (retour) {
462 retour = directory.delete();
463 }
464 return retour;
465 }
466
467
468
469
470
471
472
473 public static boolean fileExist(final String fileName, final String path) {
474 boolean exist = false;
475 final String fileString = path + File.separator + fileName;
476 final File file = new File(fileString);
477 if (file.exists()) {
478 exist = true;
479 }
480 return exist;
481 }
482
483
484
485
486
487
488
489
490 public static File[] getFiles(final File directory) {
491 if (directory == null || !directory.isDirectory()) {
492 return FILE_0_LENGTH;
493 }
494 return directory.listFiles();
495 }
496
497
498
499
500
501
502
503
504 public static void computeGlobalHash(final FilesystemBasedDigest digest,
505 final File file, final int length) {
506 if (digest == null) {
507 return;
508 }
509 final byte[] bytes = new byte[ZERO_COPY_CHUNK_SIZE];
510 int still = length;
511 int len = Math.min(still, ZERO_COPY_CHUNK_SIZE);
512 FileInputStream inputStream = null;
513 try {
514 inputStream = new FileInputStream(file);
515 int read = 1;
516 while (read > 0) {
517 read = inputStream.read(bytes, 0, len);
518 if (read <= 0) {
519 break;
520 }
521 digest.Update(bytes, 0, read);
522 still -= read;
523 if (still <= 0) {
524 break;
525 }
526 len = Math.min(still, ZERO_COPY_CHUNK_SIZE);
527 }
528 } catch (final FileNotFoundException e) {
529
530 } catch (final IOException e) {
531
532 } finally {
533 close(inputStream);
534 }
535 }
536
537
538
539
540
541
542
543
544
545 public static File[] getFiles(final File directory,
546 final FilenameFilter filter) {
547 if (directory == null || !directory.isDirectory()) {
548 return FILE_0_LENGTH;
549 }
550 return directory.listFiles(filter);
551 }
552
553
554
555
556
557
558
559
560
561 public static long uncompressedBz2File(final File fileIn,
562 final File fileOut) {
563 FileInputStream fin = null;
564 CompressorInputStream input = null;
565 FileOutputStream output = null;
566 try {
567 fin = new FileInputStream(fileIn);
568 input = new BZip2CompressorInputStream(fin);
569 output = new FileOutputStream(fileOut);
570 return copy(input, output);
571 } catch (final IOException e) {
572 SysErrLogger.FAKE_LOGGER.syserr(e);
573 return -1;
574 } finally {
575 FileUtils.close(output);
576 FileUtils.close(input);
577 FileUtils.close(fin);
578 }
579 }
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595 public static long copy(final InputStream from, final OutputStream to)
596 throws IOException {
597 checkNotNull(from);
598 checkNotNull(to);
599 final byte[] buf = new byte[ZERO_COPY_CHUNK_SIZE];
600 long total = 0;
601 while (true) {
602 final int r = from.read(buf);
603 if (r == -1) {
604 break;
605 }
606 to.write(buf, 0, r);
607 total += r;
608 }
609 return total;
610 }
611
612
613
614
615
616
617
618
619
620
621
622 public static void copy(final int blockSize, final InputStream inputStream,
623 final OutputStream out) throws IOException {
624 final byte[] buffer = new byte[blockSize];
625 while (true) {
626 final int r = inputStream.read(buffer);
627 if (r == -1) {
628 break;
629 }
630 out.write(buffer, 0, r);
631 }
632 out.flush();
633 close(out);
634 }
635
636
637
638
639
640
641
642
643
644
645 public static boolean isInSubdirectory(final File dir, final File file) {
646 if (file == null || dir == null) {
647 return false;
648 }
649 return file.equals(dir) || isInSubdirectory(dir, file.getParentFile());
650 }
651 }