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