1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.nuiton.util;
24
25 import org.apache.commons.io.FileUtils;
26 import org.apache.commons.io.IOUtils;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.lang3.SystemUtils;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 import java.io.BufferedInputStream;
33 import java.io.BufferedReader;
34 import java.io.BufferedWriter;
35 import java.io.ByteArrayOutputStream;
36 import java.io.File;
37 import java.io.FileFilter;
38 import java.io.FileInputStream;
39 import java.io.FileOutputStream;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.InputStreamReader;
43 import java.io.OutputStreamWriter;
44 import java.io.PrintStream;
45 import java.nio.CharBuffer;
46 import java.nio.MappedByteBuffer;
47 import java.nio.channels.FileChannel;
48 import java.nio.charset.Charset;
49 import java.nio.charset.CharsetDecoder;
50 import java.nio.charset.StandardCharsets;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.HashMap;
54 import java.util.LinkedList;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.regex.Matcher;
58 import java.util.regex.Pattern;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class FileUtil {
74
75 private static final Log log = LogFactory.getLog(FileUtil.class);
76
77
78
79
80
81 public static final String ENCODING = StandardCharsets.ISO_8859_1.name();
82
83
84
85
86
87
88
89
90
91 public static File byteToFile(byte[] bytes) throws IOException {
92 File file = File.createTempFile("FileUtil-byteToFile", ".tmp");
93 FileUtils.writeByteArrayToFile(file, bytes);
94 return file;
95 }
96
97
98
99
100
101
102
103
104 public static BufferedReader getReader(File file) throws IOException {
105 return getReader(file, ENCODING);
106 }
107
108
109
110
111
112
113
114
115
116
117 public static BufferedReader getReader(File file,
118 String encoding) throws IOException {
119 FileInputStream inf = new FileInputStream(file);
120 InputStreamReader in = new InputStreamReader(inf, encoding);
121 BufferedReader result = new BufferedReader(in);
122 return result;
123 }
124
125
126
127
128
129
130
131
132 public static BufferedWriter getWriter(File file) throws IOException {
133 return getWriter(file, ENCODING);
134 }
135
136
137
138
139
140
141
142
143
144
145 public static BufferedWriter getWriter(File file,
146 String encoding) throws IOException {
147 FileOutputStream outf = new FileOutputStream(file);
148 OutputStreamWriter out = new OutputStreamWriter(outf, encoding);
149 BufferedWriter result = new BufferedWriter(out);
150 return result;
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165 public static File createTempDirectory(String prefix,
166 String suffix,
167 File tmpdir) throws IOException {
168 if (tmpdir == null) {
169 tmpdir = new File(System.getProperty("java.io.tmpdir"));
170 }
171 File result = new File(tmpdir, prefix + System.currentTimeMillis() + suffix);
172 while (result.exists()) {
173 result = new File(tmpdir, prefix + System.currentTimeMillis() + suffix);
174 }
175 if (!result.mkdirs()) {
176 throw new IOException("Can't create temporary directory: " + result);
177 }
178 return result;
179 }
180
181
182
183
184
185
186
187
188
189
190 public static File createTempDirectory(String prefix,
191 String suffix) throws IOException {
192 return createTempDirectory(prefix, suffix, null);
193 }
194
195
196
197
198
199
200
201
202
203 public static File getTempFile(String content) throws IOException {
204 return getTempFile(content, "");
205 }
206
207
208
209
210
211
212
213
214
215
216 public static File getTempFile(String content,
217 String fileSuffix) throws IOException {
218 File result = File.createTempFile("tmp-" + FileUtil.class.getName(),
219 fileSuffix);
220 result.deleteOnExit();
221 FileUtils.write(result, content, Charset.defaultCharset());
222 return result;
223 }
224
225
226
227
228
229
230
231
232
233
234 public static String basename(File file, String... suffixes) {
235 String result = basename(file.getName(), suffixes);
236 return result;
237 }
238
239
240
241
242
243
244
245
246
247
248
249 public static String basename(String name, String... suffixes) {
250 String result = name;
251 for (String suffixe : suffixes) {
252 if (result.endsWith(suffixe)) {
253 result = result.substring(0,
254 result.length() - suffixe.length());
255 break;
256 }
257 }
258 return result;
259 }
260
261
262
263
264
265
266
267
268
269
270 public static String extension(File file, String... extchars) {
271 String name = file.getName();
272 String result = extension(name, extchars);
273 return result;
274 }
275
276
277
278
279
280
281
282
283
284
285
286 public static String extension(String name, String... extchars) {
287 String result = "";
288
289 if (extchars.length == 0) {
290 extchars = new String[]{"."};
291 }
292 for (String extchar : extchars) {
293 int pos = name.lastIndexOf(extchar);
294 if (pos != -1) {
295 result = name.substring(pos + extchar.length());
296 break;
297 }
298 }
299 return result;
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313 public static File changeExtension(File file,
314 String newExtension,
315 String... extchars) throws IOException {
316 String name = file.getName();
317 String newName = changeExtension(name, newExtension, extchars);
318 File newFile = new File(file.getParentFile(), newName);
319 return newFile;
320 }
321
322
323
324
325
326
327
328
329
330
331
332 public static String changeExtension(String name,
333 String newExtension,
334 String... extchars) throws IOException {
335 String extension = extension(name, extchars);
336 if (extension == null) {
337 throw new IOException("Could not find extension for name " +
338 name + " within " + Arrays.toString(extchars));
339 }
340 String nameWithoutExtension = name.substring(
341 0, name.length() - extension.length());
342 String newName = nameWithoutExtension + newExtension;
343 return newName;
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357 public static File getRelativeFile(File inputDirectory,
358 File outputDirectory,
359 File file) {
360 String inputPath = inputDirectory.getAbsolutePath();
361 String s = file.getAbsolutePath();
362 int index = s.indexOf(inputPath);
363 if (index == -1) {
364 throw new IllegalArgumentException(
365 "File " + file + " is not in " + inputDirectory);
366 }
367 String relativePath = s.substring(inputPath.length());
368 File result = new File(outputDirectory, relativePath);
369 return result;
370 }
371
372 public interface FileAction {
373 boolean doAction(File f);
374 }
375
376
377
378
379
380
381
382
383
384 public static List<File> getSubDirectories(File directory) {
385 class DirectoryFilter implements FileFilter {
386 @Override
387 public boolean accept(File f) {
388 return f.isDirectory();
389 }
390 }
391 return getFilteredElements(directory, new DirectoryFilter(), true);
392 }
393
394
395
396
397
398
399
400
401
402 public static List<File> getFiles(File directory) {
403 class NormalFileFilter implements FileFilter {
404 @Override
405 public boolean accept(File f) {
406 return f.isFile();
407 }
408 }
409 return getFilteredElements(directory, new NormalFileFilter(), true);
410 }
411
412
413
414
415
416
417
418
419
420
421
422
423 public static List<File> find(File directory,
424 final String pattern,
425 boolean recursively) {
426 final String root = directory.getAbsolutePath();
427 final int rootLength = root.length();
428
429 return getFilteredElements(directory, new FileFilter() {
430 @Override
431 public boolean accept(File f) {
432 String longFilename = f.getAbsolutePath();
433
434 String filename = longFilename.substring(rootLength + 1);
435 return filename.matches(pattern);
436 }
437 }, recursively);
438 }
439
440
441
442
443
444
445
446
447
448
449
450 public static List<File> getFilteredElements(File directory,
451 FileFilter ff,
452 boolean recursively) {
453 ArrayList<File> result = new ArrayList<File>();
454 LinkedList<File> todo = new LinkedList<File>();
455 if (directory.isDirectory()) {
456 todo.addAll(Arrays.asList(directory.listFiles()));
457 }
458 while (todo.size() > 0) {
459 File file = todo.removeFirst();
460 if (recursively && file.isDirectory()) {
461 File[] childs = file.listFiles();
462 if (childs != null) {
463
464 todo.addAll(Arrays.asList(childs));
465 }
466 }
467 if (ff == null || ff.accept(file)) {
468 result.add(file);
469 }
470 }
471 return result;
472 }
473
474
475
476
477
478
479
480
481
482
483
484
485 public static boolean walkAfter(File f, FileAction fileAction) {
486 boolean result = fileAction.doAction(f);
487 if (f.isDirectory()) {
488 File list[] = f.listFiles();
489 for (File aList : list) {
490 result = result && walkAfter(aList, fileAction);
491 }
492 }
493 return result;
494 }
495
496
497
498
499
500
501
502
503
504
505
506
507 public static boolean walkBefore(File f, FileAction fileAction) {
508 boolean result = true;
509 if (f.isDirectory()) {
510 File list[] = f.listFiles();
511 for (File aList : list) {
512 result = result && walkBefore(aList, fileAction);
513 }
514 }
515 return result && fileAction.doAction(f);
516 }
517
518
519
520
521
522
523
524
525
526
527
528
529
530 public static void copyRecursively(File srcDir,
531 File destDir,
532 String... includePatterns) throws IOException {
533 copyAndRenameRecursively(srcDir, destDir, null, null, includePatterns);
534 }
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551 public static void copyAndRenameRecursively(File srcDir, File destDir,
552 String renameFrom,
553 String renameTo,
554 String... includePatterns) throws IOException {
555 copyAndRenameRecursively(srcDir,
556 destDir,
557 true,
558 renameFrom,
559 renameTo,
560 false,
561 includePatterns
562 );
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583 public static void copyAndRenameRecursively(File srcDir,
584 File destDir,
585 boolean includeSrcDir,
586 String renameFrom,
587 String renameTo,
588 boolean exclude,
589 String... includePatterns) throws IOException {
590 String rootSrc;
591 if (includeSrcDir) {
592 rootSrc = srcDir.getParent();
593 } else {
594 rootSrc = srcDir.getPath();
595 }
596 List<File> files = getFilteredElements(srcDir, null, true);
597 log.debug("copyRecursively: " + files);
598 for (File file : files) {
599 boolean doCopy = copyRecursivelyAccept(file, includePatterns);
600 if (exclude ^ doCopy) {
601 String path = file.getPath().substring(rootSrc.length());
602 if (renameFrom != null && renameTo != null) {
603 String tmp = path.replaceAll(renameFrom, renameTo);
604 if (log.isDebugEnabled()) {
605 log.debug("rename " + path + " → " + tmp);
606 }
607 path = tmp;
608 }
609
610 File destFile = new File(destDir, path);
611 if (file.isDirectory()) {
612 log.debug("create directory: " + destFile);
613
614
615 createDirectoryIfNecessary(destFile);
616 } else {
617 log.debug("copy " + path + " to " + destFile);
618 FileUtils.copyFile(file, destFile);
619 }
620 }
621 }
622 }
623
624
625
626
627
628
629
630
631
632 public static ByteArrayOutputStream readBytesFrom(InputStream inputStream,
633 int defaultBufferSize) throws IOException {
634
635 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(
636 defaultBufferSize);
637 byte[] buffer = new byte[defaultBufferSize];
638
639 int readBytes = inputStream.read(buffer);
640 while (readBytes > 0) {
641 outputStream.write(buffer, 0, readBytes);
642 readBytes = inputStream.read(buffer);
643 }
644
645 return outputStream;
646 }
647
648
649
650
651
652
653 private static boolean copyRecursivelyAccept(File file,
654 String[] includePatterns) {
655 boolean result = includePatterns.length == 0;
656 String filename = file.getAbsolutePath();
657 for (String pattern : includePatterns) {
658 result = filename.matches(pattern);
659 if (result) {
660 break;
661 }
662 }
663 return result;
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679 protected static List<CharSequence> grep(String regex,
680 CharBuffer cb) {
681
682 List<CharSequence> linesList = null;
683
684 Pattern pattern = Pattern.compile(regex);
685
686 Pattern linePattern = Pattern.compile(".*\r?\n");
687
688 Matcher lm = linePattern.matcher(cb);
689 Matcher pm = null;
690
691 while (lm.find()) {
692
693 CharSequence cs = lm.group();
694 if (pm == null) {
695 pm = pattern.matcher(cs);
696 } else {
697 pm.reset(cs);
698 }
699 if (pm.find()) {
700
701 if (linesList == null) {
702 linesList = new ArrayList<CharSequence>();
703 }
704 linesList.add(cs);
705 }
706 if (lm.end() == cb.limit()) {
707 break;
708 }
709 }
710
711 return linesList;
712 }
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731 public static List<CharSequence> grep(String searchRegex,
732 File f,
733 String encoding) throws IOException {
734
735 List<CharSequence> lines = null;
736
737 FileInputStream fis = null;
738 FileChannel fc = null;
739
740 try {
741
742 fis = new FileInputStream(f);
743 fc = fis.getChannel();
744
745
746 int sz = (int) fc.size();
747 MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
748
749
750 Charset charset = Charset.forName(encoding);
751 CharsetDecoder decoder = charset.newDecoder();
752 CharBuffer cb = decoder.decode(bb);
753
754
755 lines = grep(searchRegex, cb);
756 } finally {
757
758 if (fc != null) {
759 fc.close();
760 }
761 if (fis != null) {
762 fis.close();
763 }
764 }
765
766 return lines;
767 }
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783 public static Map<File, List<CharSequence>> grep(String searchRegex,
784 File rootDirectory,
785 String fileRegex,
786 String encoding) throws IOException {
787 Map<File, List<CharSequence>> results =
788 new HashMap<File, List<CharSequence>>();
789 List<File> files = find(rootDirectory, fileRegex, true);
790 for (File file : files) {
791 List<CharSequence> lines = grep(searchRegex, file, encoding);
792 if (lines != null) {
793 results.put(file, lines);
794 }
795 }
796 return results;
797 }
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812 public static Map<File, List<CharSequence>> grep(String searchRegex,
813 String fileRegex,
814 String encoding) throws IOException {
815 Map<File, List<CharSequence>> results = grep(searchRegex,
816 new File("."),
817 fileRegex,
818 encoding);
819 return results;
820 }
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837 public static void sed(String searchRegex,
838 String replace,
839 File file,
840 String encoding) throws IOException {
841
842 Pattern pattern = Pattern.compile(searchRegex);
843
844 String outString = null;
845 FileInputStream fis = new FileInputStream(file);
846 try {
847
848 FileChannel fc = fis.getChannel();
849
850
851 int sz = (int) fc.size();
852 MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
853
854
855
856 Charset charset = Charset.forName(encoding);
857 CharsetDecoder decoder = charset.newDecoder();
858 CharBuffer cb = decoder.decode(bb);
859
860 Matcher matcher = pattern.matcher(cb);
861 outString = matcher.replaceAll(replace);
862 } finally {
863 fis.close();
864 }
865
866 if (outString != null) {
867 PrintStream ps = new PrintStream(new FileOutputStream(file));
868 try {
869 ps.print(outString);
870 } finally {
871 ps.close();
872 }
873 }
874 }
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890 public static void sed(String searchRegex,
891 String replace,
892 File rootDirectory,
893 String fileRegex,
894 String encoding) throws IOException {
895 List<File> files = find(rootDirectory, fileRegex, true);
896 for (File file : files) {
897 sed(searchRegex, replace, file, encoding);
898 }
899 }
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914 public static void sed(String searchRegex,
915 String replace,
916 String fileRegex,
917 String encoding) throws IOException {
918 sed(searchRegex, replace, new File("."), fileRegex, encoding);
919 }
920
921
922
923
924
925
926
927
928
929 public static boolean createDirectoryIfNecessary(File dir) {
930 if (!dir.exists()) {
931
932 return dir.mkdirs();
933 }
934 return false;
935 }
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950 public static File getFileFromPaths(File rootDirectory, String... paths) {
951 File result = rootDirectory;
952 for (String path : paths) {
953 result = new File(result, path);
954 }
955 return result;
956 }
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971 public static File getFileFromFQN(File rootDirectory, String fqn) {
972 String[] paths = fqn.split("\\.");
973
974 File result = getFileFromPaths(rootDirectory, paths);
975 return result;
976 }
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993 public static File getTestSpecificDirectory(Class<?> testClassName,
994 String methodName,
995 String classifier,
996 long timestamp) {
997 File tempDirFile = SystemUtils.getJavaIoTmpDir();
998
999
1000 String dataBasePath = testClassName.getName()
1001 + File.separator
1002 + methodName;
1003
1004 if (StringUtils.isNotBlank(classifier)) {
1005 dataBasePath += classifier;
1006 }
1007 dataBasePath += '_'
1008 + timestamp;
1009 File databaseFile = new File(tempDirFile, dataBasePath);
1010 return databaseFile;
1011 }
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021 public static boolean isGzipFile(File file) throws IOException {
1022
1023 InputStream in = new BufferedInputStream(new FileInputStream(file));
1024
1025 try {
1026 boolean gzip = GZUtil.isGzipStream(in);
1027 in.close();
1028 return gzip;
1029 } finally {
1030 IOUtils.closeQuietly(in);
1031 }
1032
1033 }
1034
1035 }