1 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
|
/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Common Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/cpl-v10.html
*
* $Id: Files.java,v 1.1.1.1.2.1 2004/07/09 01:28:37 vlad_r Exp $
*/
package com.vladium.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
// ----------------------------------------------------------------------------
/**
* @author Vlad Roubtsov, (C) 2003
*/
public
abstract class Files
{
// public: ................................................................
/**
* No duplicate elimination.
*
* @param atfile
*/
public static String [] readFileList (final File atfile)
throws IOException
{
if (atfile == null) throw new IllegalArgumentException ("null input: atfile");
List _result = null;
BufferedReader in = null;
try
{
in = new BufferedReader (new FileReader (atfile), 8 * 1024); // uses default encoding
_result = new LinkedList ();
for (String line; (line = in.readLine ()) != null; )
{
line = line.trim ();
if ((line.length () == 0) || (line.charAt (0) == '#')) continue;
_result.add (line);
}
}
finally
{
if (in != null) try { in.close (); } catch (Exception ignore) {}
}
if ((_result == null) || _result.isEmpty ())
return IConstants.EMPTY_STRING_ARRAY;
else
{
final String [] result = new String [_result.size ()];
_result.toArray (result);
return result;
}
}
/**
* Converts an array of path segments to an array of Files. The order
* of files follows the original order of path segments, except "duplicate"
* entries are removed. The definition of duplicates depends on 'canonical':
* <ul>
* <li> if 'canonical'=true, the pathnames are canonicalized via {@link #canonicalizePathname}
* before they are compared for equality
* <li> if 'canonical'=false, the pathnames are compared as case-sensitive strings
* </ul>
*
* Note that duplicate removal in classpaths affects ClassLoader.getResources().
* The first mode above makes the most sense, however the last one is what
* Sun's java.net.URLClassLoader appears to do. Hence the last mode might be
* necessary for reproducing its behavior in Sun-compatible JVMs.
*/
public static File [] pathToFiles (final String [] path, final boolean canonical)
{
if (path == null) throw new IllegalArgumentException ("null input: path");
if (path.length == 0) return IConstants.EMPTY_FILE_ARRAY;
final List /* Files */ _result = new ArrayList (path.length);
final Set /* String */ pathnames = new HashSet (path.length);
final String separators = ",".concat (File.pathSeparator);
for (int i = 0; i < path.length; ++ i)
{
String segment = path [i];
if (segment == null) throw new IllegalArgumentException ("null input: path[" + i + "]");
final StringTokenizer tokenizer = new StringTokenizer (segment, separators);
while (tokenizer.hasMoreTokens ())
{
String pathname = tokenizer.nextToken ();
if (canonical) pathname = canonicalizePathname (pathname);
if (pathnames.add (pathname))
{
_result.add (new File (pathname));
}
}
}
final File [] result = new File [_result.size ()];
_result.toArray (result);
return result;
}
/**
* Converts 'pathname' into the canonical OS form. This wrapper function
* will return the absolute form of 'pathname' if File.getCanonicalPath() fails.
*/
public static String canonicalizePathname (final String pathname)
{
if (pathname == null) throw new IllegalArgumentException ("null input: pathname");
try
{
return new File (pathname).getCanonicalPath ();
}
catch (Exception e)
{
return new File (pathname).getAbsolutePath ();
}
}
public static File canonicalizeFile (final File file)
{
if (file == null) throw new IllegalArgumentException ("null input: file");
try
{
return file.getCanonicalFile ();
}
catch (Exception e)
{
return file.getAbsoluteFile ();
}
}
/**
* Invariant: (getFileName (file) + getFileExtension (file)).equals (file.getName ()).
*
* @param file File input file descriptor [must be non-null]
*
* @return String file name without the extension [excluding '.' separator]
* [if 'file' does not appear to have an extension, the full name is returned].
*
* @throws IllegalArgumentException if 'file' is null
*/
public static String getFileName (final File file)
{
if (file == null) throw new IllegalArgumentException ("null input: file");
final String name = file.getName ();
int lastDot = name.lastIndexOf ('.');
if (lastDot < 0) return name;
return name.substring (0, lastDot);
}
/**
* Invariant: (getFileName (file) + getFileExtension (file)).equals (file.getName ()).
*
* @param file File input file descriptor [must be non-null]
*
* @return String extension [including '.' separator] or "" if 'file' does not
* appear to have an extension.
*
* @throws IllegalArgumentException if 'file' is null
*/
public static String getFileExtension (final File file)
{
if (file == null) throw new IllegalArgumentException ("null input: file");
final String name = file.getName ();
int lastDot = name.lastIndexOf ('.');
if (lastDot < 0) return "";
return name.substring (lastDot);
}
/**
*
* @param dir [null is ignored]
* @param file [absolute overrides 'dir']
* @return
*/
public static File newFile (final File dir, final File file)
{
if (file == null) throw new IllegalArgumentException ("null input: file");
if ((dir == null) || file.isAbsolute ()) return file;
return new File (dir, file.getPath ());
}
/**
*
* @param dir [null is ignored]
* @param file [absolute overrides 'dir']
* @return
*/
public static File newFile (final File dir, final String file)
{
if (file == null) throw new IllegalArgumentException ("null input: file");
final File fileFile = new File (file);
if ((dir == null) || fileFile.isAbsolute ()) return fileFile;
return new File (dir, file);
}
/**
*
* @param dir [null is ignored]
* @param file [absolute overrides 'dir']
* @return
*/
public static File newFile (final String dir, final String file)
{
if (file == null) throw new IllegalArgumentException ("null input: file");
final File fileFile = new File (file);
if ((dir == null) || fileFile.isAbsolute ()) return fileFile;
return new File (dir, file);
}
/**
* Renames 'source' to 'target' [intermediate directories are created if necessary]. If
* 'target' exists and 'overwrite' is false, the method is a no-op. No exceptions are
* thrown except for when input is invalid. If the operation fails half-way it can leave
* some file system artifacts behind.
*
* @return true iff the renaming was actually performed.
*
* @param source file descriptor [file must exist]
* @param target target file descriptor [an existing target may get deleted
* if 'overwrite' is true]
* @param overwrite if 'true', forces an existing target to be deleted
*
* @throws IllegalArgumentException if 'source' is null or file does not exist
* @throws IllegalArgumentException if 'target' is null
*/
public static boolean renameFile (final File source, final File target, final boolean overwrite)
{
if ((source == null) || ! source.exists ())
throw new IllegalArgumentException ("invalid input source: [" + source + "]");
if (target == null)
throw new IllegalArgumentException ("null input: target");
final boolean targetExists;
if (! (targetExists = target.exists ()) || overwrite)
{
if (targetExists)
{
// need to delete the target first or the rename will fail:
target.delete (); // not checking the result here: let the rename fail later
}
else
{
// note that File.renameTo() does not create intermediate directories on demand:
final File targetDir = target.getParentFile ();
if ((targetDir != null) && ! targetDir.equals (source.getParentFile ()))
targetDir.mkdirs (); // TODO: clean this up on failure?
}
// note: this can fail for a number of reasons, including the target
// being on a different drive/file system:
return source.renameTo (target);
}
return false;
}
/**
* A slightly stricter version of File.createTempFile() in J2SDK 1.3: it requires
* that the caller provide an existing parent directory for the temp file.
* This defers to File.createTempFile (prefix, extension, parentDir) after
* normalizing 'extension'.<P>
*
* MT-safety: if several threads use this API concurrently, the temp files
* created are guaranteed to get created without any collisions and correspond
* to files that did not exist before. However, if such a temp file is deleted
* at a later point, this method may reuse its file name. These MT-safety
* guarantees do not hold if files are created in the same directory outside
* of this method.
*
* @param parentDir parent dir for the temp file [may not be null and must exist]
* @param prefix prefix pattern for the temp file name [only the first 3
* chars are guaranteed to be used]
* @param extension pattern for the temp file name [null is equivalient to
* ".tmp"; this is always normalized to start with "."; only the first 3
* non-"." chars are guaranteed to be used]
*
* @return writeable temp file descriptor [incorporates 'parentDir' in its pathname]
* @throws IOException if a temp file could not be created
*/
public static File createTempFile (final File parentDir, final String prefix, String extension)
throws IOException
{
if ((parentDir == null) || ! parentDir.exists ())
throw new IllegalArgumentException ("invalid parent directory: [" + parentDir + "]");
if ((prefix == null) || (prefix.length () < 3))
throw new IllegalArgumentException ("null or less than 3 chars long: " + prefix);
if (extension == null) extension = ".tmp";
else if (extension.charAt (0) != '.') extension = ".".concat (extension);
return File.createTempFile (prefix, extension, parentDir);
}
// protected: .............................................................
// package: ...............................................................
// private: ...............................................................
private Files () {} // prevent subclassing
} // end of class
// ----------------------------------------------------------------------------
|