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