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