1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package ubic.basecode.util;
20
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileFilter;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.io.PrintWriter;
33 import java.net.URISyntaxException;
34 import java.net.URL;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Date;
38 import java.util.Enumeration;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.LinkedList;
42 import java.util.List;
43 import java.util.StringTokenizer;
44 import java.util.zip.GZIPInputStream;
45 import java.util.zip.ZipEntry;
46 import java.util.zip.ZipFile;
47
48 import org.apache.commons.lang3.StringUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52
53
54
55
56
57
58 public class FileTools {
59 private final static String PNG_EXTENSION = ".png";
60 private final static String TXT_EXTENSION = ".txt";
61
62 public final static String DEFAULT_DATA_EXTENSION = TXT_EXTENSION;
63 public final static String DEFAULT_IMAGE_EXTENSION = PNG_EXTENSION;
64
65 public final static String DEFAULT_XML_EXTENSION = ".xml";
66 protected final static String[] DATA_EXTENSIONS = { TXT_EXTENSION, ".TXT", "txt.gz", "txt.zip", "txt.gzip" };
67 protected final static String GIF_EXTENSION = ".gif";
68 protected final static String[] IMAGE_EXTENSIONS = { PNG_EXTENSION, GIF_EXTENSION, "PNG", "GIF", "JPEG", "JPG" };
69 protected final static String[] XML_EXTENSIONS = { ".XML", ".RDF-XML", ".rdf-xml.gz", ".rdf-xml.zip", ".xml.zip",
70 ".xml.gz" };
71
72 private static Logger log = LoggerFactory.getLogger( FileTools.class );
73
74
75
76
77
78 public static String addDataExtension( String filename ) {
79 return ( filename + ( FileTools.DEFAULT_DATA_EXTENSION.startsWith( "." ) ? "" : "." )
80 + FileTools.DEFAULT_DATA_EXTENSION );
81 }
82
83
84
85
86
87 public static String addImageExtension( String filename ) {
88 return ( filename + ( FileTools.DEFAULT_IMAGE_EXTENSION.startsWith( "." ) ? "" : "." )
89 + FileTools.DEFAULT_IMAGE_EXTENSION );
90 }
91
92
93
94
95
96
97 public static String changeExtension( String filename, String newExtension ) {
98
99 String filenameWithoutExtension = chompExtension( filename );
100 return ( filenameWithoutExtension + "." + newExtension );
101 }
102
103
104
105
106
107 public static void checkPathIsReadableFile( String file ) throws IOException {
108 File infile = new File( file );
109 if ( !infile.exists() || !infile.canRead() ) {
110 throw new IOException( "Could not find file: " + file );
111 }
112 }
113
114
115
116
117
118 public static String chompExtension( String filename ) {
119 int j = filename.lastIndexOf( '.' );
120 if ( j > 1 ) {
121 return filename.substring( 0, filename.lastIndexOf( '.' ) );
122 }
123 return filename;
124 }
125
126
127
128
129
130
131
132
133 public static String cleanForFileName( String name ) {
134 if ( StringUtils.isBlank( name ) ) throw new IllegalArgumentException( "'name' cannot be blank" );
135 String result = name.replaceAll( "[\\s\'\";,\\/#]+", "_" ).replaceAll( "(^_|_$)", "" );
136 if ( StringUtils.isBlank( result ) ) {
137 throw new IllegalArgumentException( "'" + name + "' was stripped down to an empty string" );
138 }
139 return result;
140 }
141
142
143
144
145
146
147
148
149 public static void copy( InputStream input, OutputStream output ) throws IOException {
150
151 if ( input.available() == 0 ) return;
152
153 byte[] buf = new byte[1024];
154 int len;
155 while ( ( len = input.read( buf ) ) > 0 ) {
156 output.write( buf, 0, len );
157 }
158 input.close();
159 output.close();
160 }
161
162
163
164
165
166
167
168
169 @SuppressWarnings("resource")
170 public static File copyPlainOrCompressedFile( final String sourcePath, String outputFilePath )
171 throws FileNotFoundException, IOException {
172 File sourceFile = new File( sourcePath );
173 if ( !sourceFile.exists() ) {
174 throw new IllegalArgumentException( "Source file (" + sourcePath + ") does not exist" );
175 }
176 if ( sourceFile.exists() && sourceFile.isDirectory() ) {
177 throw new UnsupportedOperationException( "Don't know how to copy directories (" + sourceFile + ")" );
178 }
179
180 File outputFile = new File( outputFilePath );
181 if ( outputFile.exists() && outputFile.isDirectory() ) {
182 throw new UnsupportedOperationException( "Don't know how to copy to directories (" + outputFile + ")" );
183 }
184
185 OutputStream out = new FileOutputStream( outputFile );
186
187 InputStream is = FileTools.getInputStreamFromPlainOrCompressedFile( sourcePath );
188
189 copy( is, out );
190 return outputFile;
191 }
192
193
194
195
196
197
198
199 public static File createDir( String directory ) {
200 File dirPath = new File( directory );
201 if ( !dirPath.exists() ) {
202 dirPath.mkdirs();
203 }
204 return dirPath;
205 }
206
207
208
209
210
211
212
213
214 public static int deleteDir( File directory ) {
215 int numDeleted = 0;
216 Collection<File> directories = listSubDirectories( directory );
217
218 Iterator<File> iter = directories.iterator();
219 while ( iter.hasNext() ) {
220 File dir = iter.next();
221 if ( dir.listFiles().length == 0 ) {
222 dir.getAbsoluteFile().delete();
223 numDeleted++;
224 } else {
225 log.info( "Directory not empty. Skipping deletion of " + dir.getAbsolutePath() + "." );
226 }
227 }
228
229
230 if ( directory.listFiles().length == 0 ) {
231 log.warn( "Deleting " + directory.getAbsolutePath() );
232 directory.getAbsoluteFile().delete();
233 numDeleted++;
234 } else {
235 log.info( "Directory " + directory.getAbsolutePath() + " not empty. Will not delete." );
236 }
237
238 if ( numDeleted > 1 ) log.info( "Deleted " + numDeleted + " directories." );
239 return numDeleted;
240 }
241
242
243
244
245
246
247
248
249 public static int deleteFiles( Collection<File> files ) {
250
251 int numDeleted = 0;
252
253 Iterator<File> iter = files.iterator();
254 while ( iter.hasNext() ) {
255
256 File file = iter.next();
257 if ( file.isDirectory() ) {
258 log.warn( "Cannot delete a directory." );
259 continue;
260 }
261
262 if ( log.isDebugEnabled() ) log.debug( "Deleting file " + file.getAbsolutePath() + "." );
263
264 if ( file.delete() ) {
265 numDeleted++;
266 } else {
267 log.warn( "Failed to delete: " + file + " read=" + file.canRead() + " write=" + file.canWrite() );
268 }
269
270 }
271 if ( numDeleted > 0 ) log.info( "Deleted " + numDeleted + " files." );
272 return numDeleted;
273 }
274
275
276
277
278
279
280
281
282 public static String getExtension( String filename ) {
283 String extension = null;
284 int i = filename.lastIndexOf( '.' );
285
286 if ( i > 0 && i < filename.length() - 1 ) {
287 extension = filename.substring( i + 1 ).toLowerCase();
288 }
289 return extension;
290 }
291
292
293
294
295
296
297
298
299
300 @SuppressWarnings("resource")
301 public static InputStream getInputStreamFromPlainOrCompressedFile( String fileName )
302 throws IOException, FileNotFoundException {
303 if ( !FileTools.testFile( fileName ) ) {
304 throw new IOException( "Could not read from " + fileName );
305 }
306 InputStream i;
307 if ( FileTools.isZipped( fileName ) ) {
308 log.debug( "Reading from zipped file" );
309 ZipFile f = new ZipFile( fileName );
310 ZipEntry entry = f.entries().nextElement();
311
312 if ( entry == null ) {
313 f.close();
314 throw new IOException( "No zip entries" );
315 }
316
317 if ( f.entries().hasMoreElements() ) {
318 log.debug( "ZIP archive has more then one file, reading the first one." );
319 }
320
321 i = f.getInputStream( entry );
322 } else if ( FileTools.isGZipped( fileName ) ) {
323 log.debug( "Reading from gzipped file" );
324 i = new GZIPInputStream( new FileInputStream( fileName ) );
325 } else {
326 log.debug( "Reading from uncompressed file" );
327 i = new FileInputStream( fileName );
328 }
329 return i;
330 }
331
332
333
334
335
336
337
338
339 public static List<String> getLines( File file ) throws IOException {
340 List<String> lines = new LinkedList<String>();
341 BufferedReader in = new BufferedReader( new FileReader( file ) );
342 String line;
343 while ( ( line = in.readLine() ) != null ) {
344 lines.add( line );
345 }
346 in.close();
347 return lines;
348 }
349
350
351
352
353
354
355
356 public static List<String> getLines( String filename ) throws IOException {
357 return getLines( new File( filename ) );
358 }
359
360
361
362
363
364
365
366
367
368
369
370 public static List<String> getStringListFromFile( File f ) throws Exception {
371 List<String> result = new LinkedList<String>();
372 List<String> lines = FileTools.getLines( f );
373 if ( lines.size() != 1 ) {
374 throw new RuntimeException( "Too many lines in file" );
375 }
376 String line = lines.get( 0 );
377 line = line.substring( 1, line.length() - 1 );
378 StringTokenizer toke = new StringTokenizer( line, "," );
379 while ( toke.hasMoreTokens() ) {
380 result.add( toke.nextToken().trim() );
381 }
382 return result;
383 }
384
385
386
387
388
389 public static boolean hasImageExtension( String filename ) {
390 for ( int i = 0; i < FileTools.IMAGE_EXTENSIONS.length; i++ ) {
391 if ( filename.toUpperCase().endsWith( FileTools.IMAGE_EXTENSIONS[i].toUpperCase() ) ) {
392 return true;
393 }
394 }
395 return false;
396
397 }
398
399
400
401
402
403 public static boolean hasXMLExtension( String filename ) {
404 for ( int i = 0; i < FileTools.XML_EXTENSIONS.length; i++ ) {
405 if ( filename.toUpperCase().endsWith( FileTools.XML_EXTENSIONS[i].toUpperCase() ) ) {
406 return true;
407 }
408 }
409 return false;
410 }
411
412
413
414
415
416 public static boolean isGZipped( String fileName ) {
417 String capfileName = fileName.toUpperCase();
418 if ( capfileName.endsWith( ".GZ" ) || capfileName.endsWith( ".GZIP" ) ) {
419 return true;
420 }
421 return false;
422 }
423
424
425
426
427
428 public static boolean isZipped( String filename ) {
429 String capfileName = filename.toUpperCase();
430 if ( capfileName.endsWith( ".ZIP" ) ) {
431 return true;
432 }
433 return false;
434 }
435
436
437
438
439
440
441
442
443 public static Collection<File> listDirectoryFiles( File directory ) {
444
445 if ( !directory.isDirectory() ) throw new IllegalArgumentException( "Must be a directory" );
446
447 File[] files = directory.listFiles();
448
449 FileFilter fileFilter = new FileFilter() {
450 @Override
451 public boolean accept( File file ) {
452 return file.isFile();
453 }
454 };
455 files = directory.listFiles( fileFilter );
456 return Arrays.asList( files );
457 }
458
459
460
461
462
463
464
465
466 public static Collection<File> listSubDirectories( File directory ) {
467
468 if ( !directory.isDirectory() ) throw new IllegalArgumentException( "Must be a directory" );
469
470 File[] files = directory.listFiles();
471
472 FileFilter fileFilter = new FileFilter() {
473 @Override
474 public boolean accept( File file ) {
475 return file.isDirectory();
476 }
477 };
478 files = directory.listFiles( fileFilter );
479 return Arrays.asList( files );
480 }
481
482
483
484
485
486
487 public static String resourceToPath( String resourcePath ) throws URISyntaxException {
488 if ( StringUtils.isBlank( resourcePath ) ) throw new IllegalArgumentException();
489 URL resource = FileTools.class.getResource( resourcePath );
490 if ( resource == null ) throw new IllegalArgumentException( "Could not get URL for resource=" + resourcePath );
491 return new File( resource.toURI() ).getAbsolutePath();
492 }
493
494
495
496
497 public static void stringsToFile( Collection<String> lines, File f ) throws Exception {
498 stringsToFile( lines, f, false );
499 }
500
501
502
503
504
505
506
507
508
509 public static void stringsToFile( Collection<String> lines, File f, boolean append ) throws Exception {
510 PrintWriter fout = new PrintWriter( new FileWriter( f, append ) );
511 for ( String line : lines ) {
512 fout.println( line );
513 }
514 fout.close();
515 }
516
517
518
519
520 public static void stringsToFile( Collection<String> lines, String f ) throws Exception {
521 stringsToFile( lines, new File( f ) );
522 }
523
524
525
526
527 public static void stringToFile( String s, File f ) throws Exception {
528 stringToFile( s, f, false );
529 }
530
531
532
533
534
535
536
537
538
539 public static void stringToFile( String s, File f, boolean append ) throws Exception {
540 FileWriter fout = new FileWriter( f, append );
541 fout.write( s );
542 fout.close();
543 }
544
545
546
547
548
549 public static boolean testDir( String dirname ) {
550 if ( dirname != null && dirname.length() > 0 ) {
551 File f = new File( dirname );
552 if ( f.isDirectory() && f.canRead() ) {
553 return true;
554 }
555 }
556 return false;
557 }
558
559
560
561
562
563
564
565 public static boolean testFile( File file ) {
566 if ( file != null ) {
567 if ( file.isFile() && file.canRead() ) {
568 return true;
569 }
570 }
571 return false;
572 }
573
574
575
576
577
578 public static boolean testFile( String filename ) {
579 if ( filename != null && filename.length() > 0 ) {
580 File f = new File( filename );
581 if ( f.isFile() && f.canRead() ) {
582 return true;
583 }
584 }
585 return false;
586
587 }
588
589
590
591
592
593
594
595 public static void touch( File f ) throws IOException {
596 if ( !f.exists() ) {
597 FileWriter w = new FileWriter( f );
598 w.append( "" );
599 w.close();
600 }
601 f.setLastModified( new Date().getTime() );
602 }
603
604
605
606
607
608
609
610
611
612 public static String unGzipFile( final String seekFile ) throws IOException {
613
614 if ( !isGZipped( seekFile ) ) {
615 throw new IllegalArgumentException();
616 }
617
618 checkPathIsReadableFile( seekFile );
619
620 String outputFilePath = chompExtension( seekFile );
621 File outputFile = copyPlainOrCompressedFile( seekFile, outputFilePath );
622
623 return outputFile.getAbsolutePath();
624 }
625
626
627
628
629
630
631 @SuppressWarnings("resource")
632 public static Collection<File> unZipFiles( final String seekFile ) throws IOException {
633
634 if ( !isZipped( seekFile ) ) {
635 throw new IllegalArgumentException();
636 }
637
638 checkPathIsReadableFile( seekFile );
639
640 String outputFilePath = chompExtension( seekFile );
641
642 Collection<File> result = new HashSet<File>();
643 try {
644 ZipFile f = new ZipFile( seekFile );
645 for ( Enumeration<? extends ZipEntry> entries = f.entries(); entries.hasMoreElements(); ) {
646 ZipEntry entry = entries.nextElement();
647 String outputFileTitle = entry.getName();
648 InputStream is = f.getInputStream( entry );
649
650 File out = new File( outputFilePath + outputFileTitle );
651 OutputStream os = new FileOutputStream( out );
652 copy( is, os );
653
654 result.add( out );
655 log.debug( outputFileTitle );
656 }
657
658 } catch ( IOException e ) {
659 throw new RuntimeException( e );
660 }
661
662 return result;
663 }
664
665 }