1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.utils.io;
20
21 import javax.annotation.Nonnull;
22 import javax.annotation.Nullable;
23 import javax.annotation.WillClose;
24
25 import java.io.BufferedReader;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.io.RandomAccessFile;
33 import java.io.Reader;
34 import java.io.Writer;
35 import java.net.URL;
36 import java.nio.Buffer;
37 import java.nio.ByteBuffer;
38 import java.nio.CharBuffer;
39 import java.nio.channels.FileChannel;
40 import java.nio.charset.Charset;
41 import java.nio.charset.CharsetEncoder;
42 import java.nio.charset.CoderResult;
43 import java.nio.file.Files;
44 import java.nio.file.Path;
45 import java.security.SecureRandom;
46 import java.text.DecimalFormat;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collections;
50 import java.util.List;
51 import java.util.Objects;
52 import java.util.Random;
53
54 import org.apache.commons.io.IOUtils;
55 import org.apache.maven.shared.utils.Os;
56 import org.apache.maven.shared.utils.StringUtils;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 public class FileUtils {
94
95
96
97 protected FileUtils() {
98
99 }
100
101
102
103
104 private static final int ONE_KB = 1024;
105
106
107
108
109 private static final int ONE_MB = ONE_KB * ONE_KB;
110
111
112
113
114 private static final int FILE_COPY_BUFFER_SIZE = ONE_MB * 30;
115
116
117
118
119 private static final String FS = System.getProperty("file.separator");
120
121
122
123
124
125
126
127 private static final String[] INVALID_CHARACTERS_FOR_WINDOWS_FILE_NAME = {":", "*", "?", "\"", "<", ">", "|"};
128
129
130
131
132
133 @Nonnull
134 public static String[] getDefaultExcludes() {
135 return DirectoryScanner.DEFAULTEXCLUDES;
136 }
137
138
139
140
141
142 @Nonnull
143 public static List<String> getDefaultExcludesAsList() {
144 return Arrays.asList(getDefaultExcludes());
145 }
146
147
148
149
150
151
152 @Nonnull
153 public static String getDefaultExcludesAsString() {
154 return StringUtils.join(DirectoryScanner.DEFAULTEXCLUDES, ",");
155 }
156
157
158
159
160
161
162
163
164
165 @Deprecated
166 @Nonnull
167 public static String dirname(@Nonnull String path) {
168 int i = path.lastIndexOf(File.separator);
169 return (i >= 0 ? path.substring(0, i) : "");
170 }
171
172
173
174
175
176
177
178
179 @Deprecated
180 @Nonnull
181 public static String filename(@Nonnull String path) {
182 int i = path.lastIndexOf(File.separator);
183 return (i >= 0 ? path.substring(i + 1) : path);
184 }
185
186
187
188
189
190
191
192
193
194 @Deprecated
195 @Nonnull
196 public static String extension(@Nonnull String path) {
197
198 int lastSep = path.lastIndexOf(File.separatorChar);
199 int lastDot;
200 if (lastSep < 0) {
201 lastDot = path.lastIndexOf('.');
202 } else {
203 lastDot = path.substring(lastSep + 1).lastIndexOf('.');
204 if (lastDot >= 0) {
205 lastDot += lastSep + 1;
206 }
207 }
208
209 if (lastDot >= 0 && lastDot > lastSep) {
210 return path.substring(lastDot + 1);
211 }
212
213 return "";
214 }
215
216
217
218
219
220
221
222
223 @Deprecated
224 public static boolean fileExists(@Nonnull String fileName) {
225 File file = new File(fileName);
226 return file.exists();
227 }
228
229
230
231
232
233
234
235
236
237 @Deprecated
238 @Nonnull
239 public static String fileRead(@Nonnull String file) throws IOException {
240 return fileRead(file, null);
241 }
242
243
244
245
246
247
248
249
250 @Deprecated
251 @Nonnull
252 private static String fileRead(@Nonnull String file, @Nullable String encoding) throws IOException {
253 return fileRead(new File(file), encoding);
254 }
255
256
257
258
259
260
261
262
263
264 @Deprecated
265 @Nonnull
266 public static String fileRead(@Nonnull File file) throws IOException {
267 return fileRead(file, null);
268 }
269
270
271
272
273
274
275
276
277 @Deprecated
278 @Nonnull
279 public static String fileRead(@Nonnull File file, @Nullable String encoding) throws IOException {
280 Charset charset = charset(encoding);
281
282 StringBuilder buf = new StringBuilder();
283
284 try (Reader reader = Files.newBufferedReader(file.toPath(), charset)) {
285 int count;
286 char[] b = new char[512];
287 while ((count = reader.read(b)) >= 0)
288 {
289 buf.append(b, 0, count);
290 }
291 }
292
293 return buf.toString();
294 }
295
296
297
298
299
300
301
302
303 @Deprecated
304 @Nonnull
305 public static String[] fileReadArray(@Nonnull File file) throws IOException {
306 List<String> lines = loadFile(file);
307
308 return lines.toArray(new String[lines.size()]);
309 }
310
311
312
313
314
315
316
317
318
319
320
321 @Deprecated
322 public static void fileAppend(@Nonnull String fileName, @Nonnull String data) throws IOException {
323 fileAppend(fileName, null, data);
324 }
325
326
327
328
329
330
331
332
333
334
335
336 @Deprecated
337 public static void fileAppend(@Nonnull String fileName, @Nullable String encoding, @Nonnull String data)
338 throws IOException {
339 Charset charset = charset(encoding);
340
341 try (OutputStream out = new FileOutputStream(fileName, true)) {
342 out.write(data.getBytes(charset));
343 }
344 }
345
346
347
348
349
350
351
352
353
354
355
356 @Deprecated
357 public static void fileWrite(@Nonnull String fileName, @Nonnull String data) throws IOException {
358 fileWrite(fileName, null, data);
359 }
360
361
362
363
364
365
366
367
368
369
370
371 @Deprecated
372 public static void fileWrite(@Nonnull String fileName, @Nullable String encoding, @Nonnull String data)
373 throws IOException {
374 File file = new File(fileName);
375 fileWrite(file, encoding, data);
376 }
377
378
379
380
381
382
383
384
385
386
387
388 @Deprecated
389 public static void fileWrite(@Nonnull File file, @Nullable String encoding, @Nonnull String data)
390 throws IOException {
391 Charset charset = charset(encoding);
392
393 try (Writer writer = Files.newBufferedWriter(file.toPath(), charset)) {
394 writer.write(data);
395 }
396 }
397
398
399
400
401
402
403
404
405
406
407
408 @Deprecated
409 public static void fileWriteArray(@Nonnull File file, @Nullable String... data) throws IOException {
410 fileWriteArray(file, null, data);
411 }
412
413
414
415
416
417
418
419
420
421
422
423 @Deprecated
424 public static void fileWriteArray(@Nonnull File file, @Nullable String encoding, @Nullable String... data)
425 throws IOException {
426 Charset charset = charset(encoding);
427
428 try (Writer writer = Files.newBufferedWriter(file.toPath(), charset)) {
429 for (int i = 0; data != null && i < data.length; i++) {
430 writer.write(data[i]);
431 if (i < data.length) {
432 writer.write("\n");
433 }
434 }
435 }
436 }
437
438
439
440
441
442
443
444 @Deprecated
445 public static void fileDelete(@Nonnull String fileName) {
446 File file = new File(fileName);
447
448 deleteLegacyStyle(file);
449 }
450
451
452
453
454
455
456
457
458
459
460 public static String[] getFilesFromExtension(@Nonnull String directory, @Nonnull String... extensions) {
461 List<String> files = new ArrayList<String>();
462
463 File currentDir = new File(directory);
464
465 String[] unknownFiles = currentDir.list();
466
467 if (unknownFiles == null) {
468 return new String[0];
469 }
470
471 for (String unknownFile : unknownFiles) {
472 String currentFileName = directory + System.getProperty("file.separator") + unknownFile;
473 File currentFile = new File(currentFileName);
474
475 if (currentFile.isDirectory()) {
476
477 if (currentFile.getName().equals("CVS")) {
478 continue;
479 }
480
481
482
483
484 String[] fetchFiles = getFilesFromExtension(currentFileName, extensions);
485 files = blendFilesToList(files, fetchFiles);
486 } else {
487
488
489 String add = currentFile.getAbsolutePath();
490 if (isValidFile(add, extensions)) {
491 files.add(add);
492 }
493 }
494 }
495
496
497 String[] foundFiles = new String[files.size()];
498 files.toArray(foundFiles);
499
500 return foundFiles;
501 }
502
503
504
505
506 @Nonnull
507 private static List<String> blendFilesToList(@Nonnull List<String> v, @Nonnull String... files) {
508 Collections.addAll(v, files);
509
510 return v;
511 }
512
513
514
515
516
517
518 private static boolean isValidFile(@Nonnull String file, @Nonnull String... extensions) {
519 String extension = extension(file);
520
521
522
523
524 for (String extension1 : extensions) {
525 if (extension1.equals(extension)) {
526 return true;
527 }
528 }
529
530 return false;
531 }
532
533
534
535
536
537
538
539
540
541 @Deprecated
542 public static void mkdir(@Nonnull String dir) {
543 File file = new File(dir);
544
545 if (Os.isFamily(Os.FAMILY_WINDOWS) && !isValidWindowsFileName(file)) {
546 throw new IllegalArgumentException(
547 "The file (" + dir + ") cannot contain any of the following characters: \n"
548 + StringUtils.join(INVALID_CHARACTERS_FOR_WINDOWS_FILE_NAME, " "));
549 }
550
551 if (!file.exists()) {
552
553 file.mkdirs();
554 }
555 }
556
557
558
559
560
561
562
563
564
565 public static boolean contentEquals(@Nonnull final File file1, @Nonnull final File file2) throws IOException {
566 final boolean file1Exists = file1.exists();
567 if (file1Exists != file2.exists()) {
568 return false;
569 }
570
571 if (!file1Exists) {
572
573 return true;
574 }
575
576 if (file1.isDirectory() || file2.isDirectory()) {
577
578 return false;
579 }
580
581 try (InputStream input1 = new FileInputStream(file1);
582 InputStream input2 = new FileInputStream(file2)) {
583 return IOUtils.contentEquals(input1, input2);
584 }
585 }
586
587
588
589
590
591
592
593
594 @Nullable
595 public static File toFile(@Nullable final URL url) {
596 if (url == null || !url.getProtocol().equalsIgnoreCase("file")) {
597 return null;
598 }
599
600 String filename = url.getFile().replace('/', File.separatorChar);
601 int pos = -1;
602 while ((pos = filename.indexOf('%', pos + 1)) >= 0) {
603 if (pos + 2 < filename.length()) {
604 String hexStr = filename.substring(pos + 1, pos + 3);
605 char ch = (char) Integer.parseInt(hexStr, 16);
606 filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
607 }
608 }
609 return new File(filename);
610 }
611
612
613
614
615
616
617
618
619 @Nonnull
620 public static URL[] toURLs(@Nonnull final File... files) throws IOException {
621 final URL[] urls = new URL[files.length];
622
623 for (int i = 0; i < urls.length; i++) {
624 urls[i] = files[i].toURI().toURL();
625 }
626
627 return urls;
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642 @Deprecated
643 @Nonnull
644 public static String removeExtension(@Nonnull final String filename) {
645 String ext = extension(filename);
646
647 if ("".equals(ext)) {
648 return filename;
649 }
650
651 final int index = filename.lastIndexOf(ext) - 1;
652 return filename.substring(0, index);
653 }
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668 @Deprecated
669 @Nonnull
670 public static String getExtension(@Nonnull final String filename) {
671 return extension(filename);
672 }
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688 @Deprecated
689 public static void copyFileToDirectory(@Nonnull final File source, @Nonnull final File destinationDirectory)
690 throws IOException {
691 if (destinationDirectory.exists() && !destinationDirectory.isDirectory()) {
692 throw new IOException("Destination is not a directory");
693 }
694
695 copyFile(source, new File(destinationDirectory, source.getName()));
696 }
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712 private static void copyFileToDirectoryIfModified(
713 @Nonnull final File source, @Nonnull final File destinationDirectory) throws IOException {
714 if (destinationDirectory.exists() && !destinationDirectory.isDirectory()) {
715 throw new IllegalArgumentException("Destination is not a directory");
716 }
717
718 copyFileIfModified(source, new File(destinationDirectory, source.getName()));
719 }
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735 @Deprecated
736 public static void copyFile(@Nonnull final File source, @Nonnull final File destination) throws IOException {
737
738 if (!source.exists()) {
739 final String message = "File " + source + " does not exist";
740 throw new IOException(message);
741 }
742 if (Files.isSymbolicLink(source.toPath())) {
743 File target = Files.readSymbolicLink(source.toPath()).toFile();
744 createSymbolicLink(destination, target);
745 return;
746 }
747
748
749 if (destination.exists() && Files.isSameFile(source.toPath(), destination.toPath())) {
750
751 return;
752 }
753
754 mkdirsFor(destination);
755
756 doCopyFile(source, destination);
757
758 if (source.length() != destination.length()) {
759 final String message = "Failed to copy full contents from " + source + " to " + destination;
760 throw new IOException(message);
761 }
762 }
763
764 private static void mkdirsFor(@Nonnull File destination) {
765
766 if (destination.getParentFile() != null && !destination.getParentFile().exists()) {
767
768 destination.getParentFile().mkdirs();
769 }
770 }
771
772 private static void doCopyFile(@Nonnull File source, @Nonnull File destination) throws IOException {
773
774 try (FileInputStream fis = new FileInputStream(source);
775 FileOutputStream fos = new FileOutputStream(destination);
776 FileChannel input = fis.getChannel();
777 FileChannel output = fos.getChannel()) {
778
779 long size = input.size();
780 long pos = 0;
781 long count;
782 while (pos < size) {
783 count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos;
784 pos += output.transferFrom(input, pos, count);
785 }
786 }
787
788 copyFilePermissions(source, destination);
789 }
790
791
792
793
794
795
796
797
798
799
800
801
802
803 private static boolean copyFileIfModified(@Nonnull final File source, @Nonnull final File destination)
804 throws IOException {
805 if (destination.lastModified() < source.lastModified()) {
806 copyFile(source, destination);
807
808 return true;
809 }
810
811 return false;
812 }
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831 public static void copyURLToFile(@Nonnull final URL source, @Nonnull final File destination) throws IOException {
832 copyStreamToFile(source.openStream(), destination);
833 }
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853 @Deprecated
854 private static void copyStreamToFile(@Nonnull @WillClose final InputStream source, @Nonnull final File destination)
855 throws IOException {
856
857 if (destination.getParentFile() != null && !destination.getParentFile().exists()) {
858
859 destination.getParentFile().mkdirs();
860 }
861
862
863 if (destination.exists() && !destination.canWrite()) {
864 final String message = "Unable to open file " + destination + " for writing.";
865 throw new IOException(message);
866 }
867
868 try (OutputStream out = new FileOutputStream(destination);
869 InputStream in = source) {
870 IOUtil.copy(in, out);
871 }
872 }
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893 @Deprecated
894 @Nonnull
895 public static String normalize(@Nonnull final String path) {
896 String normalized = path;
897
898 while (true) {
899 int index = normalized.indexOf("//");
900 if (index < 0) {
901 break;
902 }
903 normalized = normalized.substring(0, index) + normalized.substring(index + 1);
904 }
905
906
907 while (true) {
908 int index = normalized.indexOf("/./");
909 if (index < 0) {
910 break;
911 }
912 normalized = normalized.substring(0, index) + normalized.substring(index + 2);
913 }
914
915
916 while (true) {
917 int index = normalized.indexOf("/../");
918 if (index < 0) {
919 break;
920 }
921 if (index == 0) {
922 return null;
923 }
924 int index2 = normalized.lastIndexOf('/', index - 1);
925 normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
926 }
927
928
929 return normalized;
930 }
931
932
933
934
935
936
937
938
939
940
941 @Nonnull
942 public static File resolveFile(final File baseFile, @Nonnull String filename) {
943 String filenm = filename;
944 if ('/' != File.separatorChar) {
945 filenm = filename.replace('/', File.separatorChar);
946 }
947
948 if ('\\' != File.separatorChar) {
949 filenm = filename.replace('\\', File.separatorChar);
950 }
951
952
953 if (filenm.startsWith(File.separator) || (Os.isFamily(Os.FAMILY_WINDOWS) && filenm.indexOf(":") > 0)) {
954 File file = new File(filenm);
955
956 try {
957 file = file.getCanonicalFile();
958 } catch (final IOException ioe) {
959
960 }
961
962 return file;
963 }
964
965
966 final char[] chars = filename.toCharArray();
967 final StringBuilder sb = new StringBuilder();
968
969
970
971
972 int start = 0;
973 if ('\\' == File.separatorChar) {
974 sb.append(filenm.charAt(0));
975 start++;
976 }
977
978 for (int i = start; i < chars.length; i++) {
979 final boolean doubleSeparator = File.separatorChar == chars[i] && File.separatorChar == chars[i - 1];
980
981 if (!doubleSeparator) {
982 sb.append(chars[i]);
983 }
984 }
985
986 filenm = sb.toString();
987
988
989 File file = (new File(baseFile, filenm)).getAbsoluteFile();
990
991 try {
992 file = file.getCanonicalFile();
993 } catch (final IOException ioe) {
994
995 }
996
997 return file;
998 }
999
1000
1001
1002
1003
1004
1005
1006
1007 @Deprecated
1008 public static void forceDelete(@Nonnull final String file) throws IOException {
1009 forceDelete(new File(file));
1010 }
1011
1012
1013
1014
1015
1016
1017
1018
1019 @Deprecated
1020 public static void forceDelete(@Nonnull final File file) throws IOException {
1021 if (file.isDirectory()) {
1022 deleteDirectory(file);
1023 } else {
1024
1025
1026
1027
1028 boolean filePresent = file.getCanonicalFile().exists();
1029 if (!deleteFile(file) && filePresent) {
1030 final String message = "File " + file + " unable to be deleted.";
1031 throw new IOException(message);
1032 }
1033 }
1034 }
1035
1036
1037
1038
1039
1040
1041
1042
1043 @Deprecated
1044 public static void delete(@Nonnull File file) throws IOException {
1045 Files.delete(file.toPath());
1046 }
1047
1048
1049
1050
1051
1052
1053 @Deprecated
1054 public static boolean deleteLegacyStyle(@Nonnull File file) {
1055 try {
1056 Files.delete(file.toPath());
1057 return true;
1058 } catch (IOException e) {
1059 return false;
1060 }
1061 }
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071 private static boolean deleteFile(@Nonnull File file) throws IOException {
1072 if (file.isDirectory()) {
1073 throw new IOException("File " + file + " isn't a file.");
1074 }
1075
1076 if (!deleteLegacyStyle(file)) {
1077 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
1078 file = file.getCanonicalFile();
1079 }
1080
1081 try {
1082 Thread.sleep(10);
1083 return deleteLegacyStyle(file);
1084 } catch (InterruptedException ex) {
1085 return deleteLegacyStyle(file);
1086 }
1087 }
1088
1089 return true;
1090 }
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 public static void forceMkdir(@Nonnull final File file) throws IOException {
1101 if (Os.isFamily(Os.FAMILY_WINDOWS) && !isValidWindowsFileName(file)) {
1102 throw new IllegalArgumentException(
1103 "The file (" + file.getAbsolutePath() + ") cannot contain any of the following characters: \n"
1104 + StringUtils.join(INVALID_CHARACTERS_FOR_WINDOWS_FILE_NAME, " "));
1105 }
1106
1107 if (file.exists()) {
1108 if (file.isFile()) {
1109 final String message =
1110 "File " + file + " exists and is " + "not a directory. Unable to create directory.";
1111 throw new IOException(message);
1112 }
1113 } else {
1114 if (!file.mkdirs()) {
1115 final String message = "Unable to create directory " + file;
1116 throw new IOException(message);
1117 }
1118 }
1119 }
1120
1121
1122
1123
1124
1125
1126
1127
1128 @Deprecated
1129 public static void deleteDirectory(@Nonnull final String directory) throws IOException {
1130 deleteDirectory(new File(directory));
1131 }
1132
1133
1134
1135
1136
1137
1138
1139
1140 @Deprecated
1141 public static void deleteDirectory(@Nonnull final File directory) throws IOException {
1142 if (!directory.exists()) {
1143 return;
1144 }
1145
1146
1147
1148
1149 if (deleteLegacyStyle(directory)) {
1150 return;
1151 }
1152
1153 cleanDirectory(directory);
1154 if (!deleteLegacyStyle(directory)) {
1155 final String message = "Directory " + directory + " unable to be deleted.";
1156 throw new IOException(message);
1157 }
1158 }
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 @Deprecated
1169 public static void cleanDirectory(@Nonnull final File directory) throws IOException {
1170 if (!directory.exists()) {
1171 final String message = directory + " does not exist";
1172 throw new IllegalArgumentException(message);
1173 }
1174
1175 if (!directory.isDirectory()) {
1176 final String message = directory + " is not a directory";
1177 throw new IllegalArgumentException(message);
1178 }
1179
1180 IOException exception = null;
1181
1182 final File[] files = directory.listFiles();
1183
1184 if (files == null) {
1185 return;
1186 }
1187
1188 for (final File file : files) {
1189 try {
1190 forceDelete(file);
1191 } catch (final IOException ioe) {
1192 exception = ioe;
1193 }
1194 }
1195
1196 if (null != exception) {
1197 throw exception;
1198 }
1199 }
1200
1201
1202
1203
1204
1205
1206
1207
1208 @Deprecated
1209 public static long sizeOfDirectory(@Nonnull final String directory) {
1210 return sizeOfDirectory(new File(directory));
1211 }
1212
1213
1214
1215
1216
1217
1218
1219
1220 @Deprecated
1221 public static long sizeOfDirectory(@Nonnull final File directory) {
1222 if (!directory.exists()) {
1223 final String message = directory + " does not exist";
1224 throw new IllegalArgumentException(message);
1225 }
1226
1227 if (!directory.isDirectory()) {
1228 final String message = directory + " is not a directory";
1229 throw new IllegalArgumentException(message);
1230 }
1231
1232 long size = 0;
1233
1234 final File[] files = directory.listFiles();
1235 if (files == null) {
1236 throw new IllegalArgumentException("Problems reading directory");
1237 }
1238
1239 for (final File file : files) {
1240 if (file.isDirectory()) {
1241 size += sizeOfDirectory(file);
1242 } else {
1243 size += file.length();
1244 }
1245 }
1246
1247 return size;
1248 }
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 @Nonnull
1262 public static List<File> getFiles(@Nonnull File directory, @Nullable String includes, @Nullable String excludes)
1263 throws IOException {
1264 return getFiles(directory, includes, excludes, true);
1265 }
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 @Nonnull
1279 public static List<File> getFiles(
1280 @Nonnull File directory, @Nullable String includes, @Nullable String excludes, boolean includeBasedir)
1281 throws IOException {
1282 List<String> fileNames = getFileNames(directory, includes, excludes, includeBasedir);
1283
1284 List<File> files = new ArrayList<File>();
1285
1286 for (String filename : fileNames) {
1287 files.add(new File(filename));
1288 }
1289
1290 return files;
1291 }
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304 @Nonnull
1305 public static List<String> getFileNames(
1306 @Nonnull File directory, @Nullable String includes, @Nullable String excludes, boolean includeBasedir)
1307 throws IOException {
1308 return getFileNames(directory, includes, excludes, includeBasedir, true);
1309 }
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 @Nonnull
1323 private static List<String> getFileNames(
1324 @Nonnull File directory,
1325 @Nullable String includes,
1326 @Nullable String excludes,
1327 boolean includeBasedir,
1328 boolean isCaseSensitive)
1329 throws IOException {
1330 return getFileAndDirectoryNames(directory, includes, excludes, includeBasedir, isCaseSensitive, true, false);
1331 }
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344 @Nonnull
1345 public static List<String> getDirectoryNames(
1346 @Nonnull File directory, @Nullable String includes, @Nullable String excludes, boolean includeBasedir)
1347 throws IOException {
1348 return getDirectoryNames(directory, includes, excludes, includeBasedir, true);
1349 }
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 @Nonnull
1363 public static List<String> getDirectoryNames(
1364 @Nonnull File directory,
1365 @Nullable String includes,
1366 @Nullable String excludes,
1367 boolean includeBasedir,
1368 boolean isCaseSensitive)
1369 throws IOException {
1370 return getFileAndDirectoryNames(directory, includes, excludes, includeBasedir, isCaseSensitive, false, true);
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385 @Nonnull
1386 public static List<String> getFileAndDirectoryNames(
1387 File directory,
1388 @Nullable String includes,
1389 @Nullable String excludes,
1390 boolean includeBasedir,
1391 boolean isCaseSensitive,
1392 boolean getFiles,
1393 boolean getDirectories) {
1394 DirectoryScanner scanner = new DirectoryScanner();
1395
1396 scanner.setBasedir(directory);
1397
1398 if (includes != null) {
1399 scanner.setIncludes(StringUtils.split(includes, ","));
1400 }
1401
1402 if (excludes != null) {
1403 scanner.setExcludes(StringUtils.split(excludes, ","));
1404 }
1405
1406 scanner.setCaseSensitive(isCaseSensitive);
1407
1408 scanner.scan();
1409
1410 List<String> list = new ArrayList<String>();
1411
1412 if (getFiles) {
1413 String[] files = scanner.getIncludedFiles();
1414
1415 for (String file : files) {
1416 if (includeBasedir) {
1417 list.add(directory + FileUtils.FS + file);
1418 } else {
1419 list.add(file);
1420 }
1421 }
1422 }
1423
1424 if (getDirectories) {
1425 String[] directories = scanner.getIncludedDirectories();
1426
1427 for (String directory1 : directories) {
1428 if (includeBasedir) {
1429 list.add(directory + FileUtils.FS + directory1);
1430 } else {
1431 list.add(directory1);
1432 }
1433 }
1434 }
1435
1436 return list;
1437 }
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448 @Deprecated
1449 public static void copyDirectory(@Nonnull File sourceDirectory, @Nonnull File destinationDirectory)
1450 throws IOException {
1451 Objects.requireNonNull(sourceDirectory);
1452 Objects.requireNonNull(destinationDirectory);
1453 if (destinationDirectory.equals(sourceDirectory)) {
1454 throw new IOException("Can't copy directory " + sourceDirectory + " to itself.");
1455 } else if (!destinationDirectory.exists()) {
1456 if (!destinationDirectory.mkdirs()) {
1457 throw new IOException("Can't create directory " + destinationDirectory);
1458 }
1459 }
1460 copyDirectoryStructure(sourceDirectory, destinationDirectory);
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474 @Deprecated
1475 public static void copyDirectory(
1476 @Nonnull File sourceDirectory,
1477 @Nonnull File destinationDirectory,
1478 @Nullable String includes,
1479 @Nullable String excludes)
1480 throws IOException {
1481 if (!sourceDirectory.exists()) {
1482 return;
1483 } else if (!sourceDirectory.isDirectory()) {
1484 throw new IOException(sourceDirectory + " is not a directory.");
1485 }
1486
1487 List<File> files = getFiles(sourceDirectory, includes, excludes);
1488
1489 for (File file : files) {
1490 copyFileToDirectory(file, destinationDirectory);
1491 }
1492 }
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507 @Deprecated
1508 public static void copyDirectoryStructure(@Nonnull File sourceDirectory, @Nonnull File destinationDirectory)
1509 throws IOException {
1510 copyDirectoryStructure(sourceDirectory, destinationDirectory, destinationDirectory, false);
1511 }
1512
1513 private static void copyDirectoryStructure(
1514 @Nonnull File sourceDirectory,
1515 @Nonnull File destinationDirectory,
1516 File rootDestinationDirectory,
1517 boolean onlyModifiedFiles)
1518 throws IOException {
1519
1520 if (sourceDirectory == null) {
1521 throw new IOException("source directory can't be null.");
1522 }
1523
1524
1525 if (destinationDirectory == null) {
1526 throw new IOException("destination directory can't be null.");
1527 }
1528
1529 if (sourceDirectory.equals(destinationDirectory)) {
1530 throw new IOException("source and destination are the same directory.");
1531 }
1532
1533 if (!sourceDirectory.exists()) {
1534 throw new IOException("Source directory doesn't exist (" + sourceDirectory.getAbsolutePath() + ").");
1535 }
1536
1537 File[] files = sourceDirectory.listFiles();
1538
1539 if (files == null) {
1540 return;
1541 }
1542
1543 String sourcePath = sourceDirectory.getAbsolutePath();
1544
1545 for (File file : files) {
1546 if (file.equals(rootDestinationDirectory)) {
1547
1548 continue;
1549 }
1550
1551 String dest = file.getAbsolutePath();
1552
1553 dest = dest.substring(sourcePath.length() + 1);
1554
1555 File destination = new File(destinationDirectory, dest);
1556
1557 if (file.isFile()) {
1558 destination = destination.getParentFile();
1559
1560 if (onlyModifiedFiles) {
1561 copyFileToDirectoryIfModified(file, destination);
1562 } else {
1563 copyFileToDirectory(file, destination);
1564 }
1565 } else if (file.isDirectory()) {
1566 if (!destination.exists() && !destination.mkdirs()) {
1567 throw new IOException(
1568 "Could not create destination directory '" + destination.getAbsolutePath() + "'.");
1569 }
1570
1571 copyDirectoryStructure(file, destination, rootDestinationDirectory, onlyModifiedFiles);
1572 } else {
1573 throw new IOException("Unknown file type: " + file.getAbsolutePath());
1574 }
1575 }
1576 }
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591 @Deprecated
1592 public static void rename(@Nonnull File from, @Nonnull File to) throws IOException {
1593 if (to.exists() && !deleteLegacyStyle(to)) {
1594 throw new IOException("Failed to delete " + to + " while trying to rename " + from);
1595 }
1596
1597 File parent = to.getParentFile();
1598 if (parent != null && !parent.exists() && !parent.mkdirs()) {
1599 throw new IOException("Failed to create directory " + parent + " while trying to rename " + from);
1600 }
1601
1602 if (!from.renameTo(to)) {
1603 copyFile(from, to);
1604 if (!deleteLegacyStyle(from)) {
1605 throw new IOException("Failed to delete " + from + " while trying to rename it.");
1606 }
1607 }
1608 }
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632 @Deprecated
1633 public static File createTempFile(@Nonnull String prefix, @Nonnull String suffix, @Nullable File parentDir) {
1634 File result;
1635 String parent = System.getProperty("java.io.tmpdir");
1636 if (parentDir != null) {
1637 parent = parentDir.getPath();
1638 }
1639 DecimalFormat fmt = new DecimalFormat("#####");
1640 SecureRandom secureRandom = new SecureRandom();
1641 long secureInitializer = secureRandom.nextLong();
1642 Random rand = new Random(secureInitializer + Runtime.getRuntime().freeMemory());
1643 do {
1644 result = new File(parent, prefix + fmt.format(positiveRandom(rand)) + suffix);
1645 } while (result.exists());
1646
1647 return result;
1648 }
1649
1650 private static int positiveRandom(Random rand) {
1651 int a = rand.nextInt();
1652 while (a == Integer.MIN_VALUE) {
1653 a = rand.nextInt();
1654 }
1655 return Math.abs(a);
1656 }
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667 public static void copyFile(
1668 @Nonnull File from, @Nonnull File to, @Nullable String encoding, @Nullable FilterWrapper... wrappers)
1669 throws IOException {
1670 copyFile(from, to, encoding, wrappers, false);
1671 }
1672
1673
1674
1675
1676 public abstract static class FilterWrapper {
1677
1678
1679
1680
1681 public abstract Reader getReader(Reader fileReader);
1682 }
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696 public static void copyFile(
1697 @Nonnull File from,
1698 @Nonnull File to,
1699 @Nullable String encoding,
1700 @Nullable FilterWrapper[] wrappers,
1701 boolean overwrite)
1702 throws IOException {
1703 if (wrappers == null || wrappers.length == 0) {
1704 if (overwrite || !to.exists() || to.lastModified() < from.lastModified()) {
1705 copyFile(from, to);
1706 }
1707 } else {
1708 Charset charset = charset(encoding);
1709
1710
1711 try (Reader fileReader = Files.newBufferedReader(from.toPath(), charset)) {
1712 Reader wrapped = fileReader;
1713 for (FilterWrapper wrapper : wrappers) {
1714 wrapped = wrapper.getReader(wrapped);
1715 }
1716
1717 if (overwrite || !to.exists()) {
1718 try (Writer fileWriter = Files.newBufferedWriter(to.toPath(), charset)) {
1719 IOUtil.copy(wrapped, fileWriter);
1720 }
1721 } else {
1722 CharsetEncoder encoder = charset.newEncoder();
1723
1724 int totalBufferSize = FILE_COPY_BUFFER_SIZE;
1725
1726 int charBufferSize = (int) Math.floor(totalBufferSize / (2 + 2 * encoder.maxBytesPerChar()));
1727 int byteBufferSize = (int) Math.ceil(charBufferSize * encoder.maxBytesPerChar());
1728
1729 CharBuffer newChars = CharBuffer.allocate(charBufferSize);
1730 ByteBuffer newBytes = ByteBuffer.allocate(byteBufferSize);
1731 ByteBuffer existingBytes = ByteBuffer.allocate(byteBufferSize);
1732
1733 CoderResult coderResult;
1734 int existingRead;
1735 boolean writing = false;
1736
1737 try (RandomAccessFile existing = new RandomAccessFile(to, "rw")) {
1738 int n;
1739 while (-1 != (n = wrapped.read(newChars))) {
1740 ((Buffer) newChars).flip();
1741
1742 coderResult = encoder.encode(newChars, newBytes, n != 0);
1743 if (coderResult.isError()) {
1744 coderResult.throwException();
1745 }
1746
1747 ((Buffer) newBytes).flip();
1748
1749 if (!writing) {
1750 existingRead = existing.read(existingBytes.array(), 0, newBytes.remaining());
1751 ((Buffer) existingBytes).position(existingRead);
1752 ((Buffer) existingBytes).flip();
1753
1754 if (newBytes.compareTo(existingBytes) != 0) {
1755 writing = true;
1756 if (existingRead > 0) {
1757 existing.seek(existing.getFilePointer() - existingRead);
1758 }
1759 }
1760 }
1761
1762 if (writing) {
1763 existing.write(newBytes.array(), 0, newBytes.remaining());
1764 }
1765
1766 ((Buffer) newChars).clear();
1767 ((Buffer) newBytes).clear();
1768 ((Buffer) existingBytes).clear();
1769 }
1770
1771 if (existing.length() > existing.getFilePointer()) {
1772 existing.setLength(existing.getFilePointer());
1773 }
1774 }
1775 }
1776 }
1777 }
1778
1779 copyFilePermissions(from, to);
1780 }
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792 private static void copyFilePermissions(@Nonnull File source, @Nonnull File destination) throws IOException {
1793 try {
1794
1795 Files.setPosixFilePermissions(destination.toPath(), Files.getPosixFilePermissions(source.toPath()));
1796 } catch (UnsupportedOperationException e) {
1797
1798 destination.setExecutable(source.canExecute());
1799 destination.setReadable(source.canRead());
1800 destination.setWritable(source.canWrite());
1801 }
1802 }
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812 @Deprecated
1813 @Nonnull
1814 public static List<String> loadFile(@Nonnull File file) throws IOException {
1815 List<String> lines = new ArrayList<String>();
1816
1817 if (file.exists()) {
1818 try (BufferedReader reader = Files.newBufferedReader(file.toPath(), Charset.defaultCharset())) {
1819 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
1820 line = line.trim();
1821 if (!line.startsWith("#") && line.length() != 0) {
1822 lines.add(line);
1823 }
1824 }
1825 }
1826 }
1827
1828 return lines;
1829 }
1830
1831
1832
1833
1834
1835
1836 private static Charset charset(String encoding) {
1837 if (encoding == null || encoding.isEmpty()) {
1838 return Charset.defaultCharset();
1839 } else {
1840 return Charset.forName(encoding);
1841 }
1842 }
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853 private static boolean isValidWindowsFileName(@Nonnull File f) {
1854 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
1855 if (StringUtils.indexOfAny(f.getName(), INVALID_CHARACTERS_FOR_WINDOWS_FILE_NAME) != -1) {
1856 return false;
1857 }
1858
1859 if (f.getParentFile() != null) {
1860 return isValidWindowsFileName(f.getParentFile());
1861 }
1862 }
1863
1864 return true;
1865 }
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875 @Deprecated
1876 public static boolean isSymbolicLink(@Nonnull final File file) throws IOException {
1877 return Files.isSymbolicLink(file.toPath());
1878 }
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889 @Deprecated
1890 public static boolean isSymbolicLinkForSure(@Nonnull final File file) throws IOException {
1891 return Files.isSymbolicLink(file.toPath());
1892 }
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904 @Nonnull
1905 public static File createSymbolicLink(@Nonnull File symlink, @Nonnull File target) throws IOException {
1906 final Path symlinkPath = symlink.toPath();
1907
1908 if (Files.exists(symlinkPath)) {
1909 if (target.equals(Files.readSymbolicLink(symlinkPath).toFile())) {
1910 return symlink;
1911 }
1912
1913 Files.delete(symlinkPath);
1914 }
1915
1916 return Files.createSymbolicLink(symlinkPath, target.toPath()).toFile();
1917 }
1918 }