001 package com.croftsoft.core.io; 002 003 import java.io.*; 004 import java.util.*; 005 006 import com.croftsoft.core.lang.NullArgumentException; 007 008 /********************************************************************* 009 * A library of static methods to manipulate File objects. 010 * 011 * <p /> 012 * 013 * @version 014 * 2001-06-10 015 * @since 016 * 1999-08-15 017 * @author 018 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 019 *********************************************************************/ 020 021 public final class FileLib 022 ////////////////////////////////////////////////////////////////////// 023 ////////////////////////////////////////////////////////////////////// 024 { 025 026 /********************************************************************* 027 * Test method. 028 *********************************************************************/ 029 public static void main ( String [ ] args ) 030 ////////////////////////////////////////////////////////////////////// 031 { 032 File file = findFile ( args [ 0 ], args [ 1 ], true ); 033 System.out.println ( file ); 034 } 035 036 /********************************************************************* 037 * Returns null if the file does not already exist. 038 *********************************************************************/ 039 public static File findFile ( 040 String dirname, String filename, boolean ignoreFilenameCase ) 041 ////////////////////////////////////////////////////////////////////// 042 { 043 File file = new File ( dirname, filename ); 044 if ( file.exists ( ) ) return file; 045 if ( !ignoreFilenameCase ) return null; 046 047 File dir = null; 048 049 if ( dirname != null ) 050 { 051 dir = new File ( dirname ); 052 if ( !dir.exists ( ) ) return null; 053 if ( !dir.isDirectory ( ) ) 054 { 055 throw new IllegalArgumentException ( 056 "\"" + dirname + "\" is not a directory." ); 057 } 058 } 059 060 if ( dir == null ) dir = new File ( "." ); 061 062 String [ ] files = dir.list ( ); 063 for ( int i = 0; i < files.length; i++ ) 064 { 065 if ( files [ i ].equalsIgnoreCase ( filename ) ) 066 { 067 return new File ( dir, files [ i ] ); 068 } 069 } 070 071 return null; 072 } 073 074 /********************************************************************* 075 * Parses out the file name extension. 076 * <P> 077 * @return 078 * Returns null if file name does not have a period;<BR> 079 * returns the empty String ("") if the file name has only one period 080 * and it is the last character;<BR> 081 * otherwise returns everything after the first period. 082 *********************************************************************/ 083 public static String getExtension ( File file ) 084 ////////////////////////////////////////////////////////////////////// 085 { 086 String name = file.getName ( ); 087 int i = name.indexOf ( '.' ); 088 if ( i < 0 ) return null; 089 return name.substring ( i + 1, name.length ( ) - i - 1 ); 090 } 091 092 /********************************************************************* 093 * Creates the parent directories for a file specified by a combined 094 * path and filename String. 095 * The name after the last separator in pathFilename is not created 096 * as a directory and is typically a filename. 097 * Used when the normal File.mkdirs() operation would mistakenly create 098 * directories for the parent directories plus a directory with the 099 * same name as the filename instead of just directories for the 100 * parent directories when given the combined path and filename. 101 * The pathFilename may be just a filename without a path or a 102 * a file in the root directory; in these cases, no directory will 103 * be created. 104 *********************************************************************/ 105 public static boolean makeParents ( String pathFilename ) 106 ////////////////////////////////////////////////////////////////////// 107 { 108 File file = new File ( pathFilename ); 109 110 String parent = file.getParent ( ); 111 112 if ( parent == null ) 113 { 114 return false; 115 } 116 117 File dir = new File ( parent ); 118 119 return dir.mkdirs ( ); 120 } 121 122 /********************************************************************* 123 * Replaces instances of oldString with newString in the inFile. 124 * <P> 125 * Creates a temporary file (inFile + ".tmp") in the process. 126 * 127 * @return 128 * Returns true if the file was updated. 129 *********************************************************************/ 130 public static boolean replaceStrings ( 131 File file, String oldString, String newString ) 132 throws FileNotFoundException, IOException 133 ////////////////////////////////////////////////////////////////////// 134 { 135 byte [ ] oldBytes = oldString.getBytes ( ); 136 byte [ ] newBytes = newString.getBytes ( ); 137 return replaceBytes ( file, oldBytes, newBytes ); 138 } 139 140 /********************************************************************* 141 * Replaces instances of oldBytes with newBytes in the inFile. 142 * <P> 143 * Creates a temporary file (inFile + ".tmp") in the process. 144 * 145 * @return 146 * Returns true if the file was updated. 147 *********************************************************************/ 148 public static boolean replaceBytes ( 149 File file, byte [ ] oldBytes, byte [ ] newBytes ) 150 throws FileNotFoundException, IOException 151 ////////////////////////////////////////////////////////////////////// 152 { 153 String fileName = file.getCanonicalPath ( ); 154 String tmpFileName = fileName + ".tmp"; 155 File tmpFile = new File ( tmpFileName ); 156 if ( tmpFile.exists ( ) ) 157 { 158 throw new IOException ( "Temporary file \"" + tmpFileName 159 + "\" already exists." ); 160 } 161 try 162 { 163 boolean hasChanged 164 = replaceBytes ( file, tmpFile, oldBytes, newBytes ); 165 if ( !hasChanged ) return false; 166 if ( !file.delete ( ) ) 167 { 168 throw new IOException ( "Unable to delete to replace \"" 169 + fileName + "\"." ); 170 } 171 if ( !tmpFile.renameTo ( new File ( fileName ) ) ) 172 { 173 throw new IOException ( "Original file deleted but unable" 174 + " to rename the updated file to the original name (\"" 175 + fileName + "\", \"" + tmpFileName + "\")." ); 176 } 177 } 178 finally 179 { 180 tmpFile.delete ( ); 181 } 182 return true; 183 } 184 185 /********************************************************************* 186 * Copies inFile to outFile with the replacement of occurrences of 187 * oldString with newString. 188 * <P> 189 * Any pre-existing outFile is overwritten. 190 * 191 * @return 192 * Returns true if outFile differs from inFile. 193 *********************************************************************/ 194 public static boolean replaceStrings ( 195 File inFile, File outFile, String oldString, String newString ) 196 throws FileNotFoundException, IOException 197 ////////////////////////////////////////////////////////////////////// 198 { 199 byte [ ] oldBytes = oldString.getBytes ( ); 200 byte [ ] newBytes = newString.getBytes ( ); 201 return replaceBytes ( inFile, outFile, oldBytes, newBytes ); 202 } 203 204 /********************************************************************* 205 * Copies inFile to outFile with the replacement of occurrences of 206 * oldBytes with newBytes. 207 * <P> 208 * Any pre-existing outFile is overwritten. 209 * 210 * @return 211 * Returns true if outFile differs from inFile. 212 *********************************************************************/ 213 public static boolean replaceBytes ( 214 File inFile, 215 File outFile, 216 byte [ ] oldBytes, 217 byte [ ] newBytes ) 218 throws FileNotFoundException, IOException 219 ////////////////////////////////////////////////////////////////////// 220 { 221 if ( ( inFile == null ) 222 || ( outFile == null ) 223 || ( oldBytes == null ) 224 || ( newBytes == null ) ) 225 { 226 throw new IllegalArgumentException ( "null argument" ); 227 } 228 229 if ( !inFile.isFile ( ) ) 230 { 231 throw new IllegalArgumentException ( 232 "\"" + inFile.getCanonicalPath ( ) + "\" is not a file." ); 233 } 234 /* 235 if ( !outFile.isFile ( ) ) 236 { 237 throw new IllegalArgumentException ( 238 "\"" + outFile.getCanonicalPath ( ) + "\" is not a file." ); 239 } 240 */ 241 242 BufferedInputStream in = new BufferedInputStream ( 243 new FileInputStream ( inFile ) ); 244 BufferedOutputStream out = new BufferedOutputStream ( 245 new FileOutputStream ( outFile ) ); 246 247 boolean hasChanged 248 = StreamLib.replaceBytes ( in, out, oldBytes, newBytes ); 249 250 out.close ( ); 251 in.close ( ); 252 253 return hasChanged; 254 } 255 256 /********************************************************************* 257 * Loads the text file content into a String. 258 *********************************************************************/ 259 public static String loadTextFile ( String filename ) 260 throws IOException 261 ////////////////////////////////////////////////////////////////////// 262 { 263 if ( filename == null ) 264 { 265 throw new IllegalArgumentException ( "null filename" ); 266 } 267 268 FileReader in = null; 269 270 StringWriter out = null; 271 272 try 273 { 274 in = new FileReader ( filename ); 275 276 out = new StringWriter ( ); 277 278 int i; 279 280 while ( ( i = in.read ( ) ) > -1 ) 281 { 282 out.write ( ( byte ) i ); 283 } 284 285 out.flush ( ); 286 287 return out.toString ( ); 288 } 289 finally 290 { 291 try { in.close ( ); } catch ( Exception ex ) { } 292 293 try { out.close ( ); } catch ( Exception ex ) { } 294 } 295 } 296 297 /********************************************************************* 298 * Strips off the file name extension. 299 *********************************************************************/ 300 public static String pareExtension ( String fileName ) 301 ////////////////////////////////////////////////////////////////////// 302 { 303 if ( fileName == null ) 304 { 305 throw new IllegalArgumentException ( "null" ); 306 } 307 308 int index = fileName.lastIndexOf ( '.' ); 309 310 if ( index < 0 ) 311 { 312 return fileName; 313 } 314 315 return fileName.substring ( 0, index ); 316 } 317 318 /********************************************************************* 319 * Saves text to a file. 320 *********************************************************************/ 321 public static void saveTextFile ( 322 String filename, 323 String text ) 324 throws IOException 325 ////////////////////////////////////////////////////////////////////// 326 { 327 NullArgumentException.check ( filename ); 328 329 NullArgumentException.check ( text ); 330 331 FileWriter fileWriter = null; 332 333 try 334 { 335 fileWriter = new FileWriter ( filename ); 336 337 fileWriter.write ( text ); 338 } 339 finally 340 { 341 if ( fileWriter != null ) 342 { 343 fileWriter.close ( ); 344 } 345 } 346 } 347 348 ////////////////////////////////////////////////////////////////////// 349 ////////////////////////////////////////////////////////////////////// 350 351 private FileLib ( ) { } 352 353 ////////////////////////////////////////////////////////////////////// 354 ////////////////////////////////////////////////////////////////////// 355 }