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="http://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 }