null.
* @param destFile Name of file to copy to.
* Must not be null.
*
* @throws IOException if the copying fails.
*/
public void copyFile(String sourceFile, String destFile) throws IOException {
copyFile(new File(sourceFile), new File(destFile), null, false, false);
}
/**
* Convenience method to copy a file from a source to a destination
* specifying if token filtering must be used.
*
* @param sourceFile Name of file to copy from.
* Must not be null.
* @param destFile Name of file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
*
* @throws IOException if the copying fails.
*/
public void copyFile(String sourceFile, String destFile, FilterSetCollection filters)
throws IOException {
copyFile(new File(sourceFile), new File(destFile), filters, false, false);
}
/**
* Convenience method to copy a file from a source to a destination specifying if token
* filtering must be used and if source files may overwrite newer destination files.
*
* @param sourceFile Name of file to copy from. Must not be null.
* @param destFile Name of file to copy to. Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param overwrite Whether or not the destination file should be overwritten if it already
* exists.
*
* @throws IOException if the copying fails.
*/
public void copyFile(String sourceFile, String destFile, FilterSetCollection filters,
boolean overwrite) throws IOException {
copyFile(new File(sourceFile), new File(destFile), filters, overwrite, false);
}
/**
* Convenience method to copy a file from a source to a destination
* specifying if token
* filtering must be used, if source files may overwrite newer destination
* files and the last
* modified time of destFile file should be made equal to
* the last modified time
* of sourceFile.
*
* @param sourceFile Name of file to copy from. Must not be null.
* @param destFile Name of file to copy to. Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file
* should be set to that of the source file.
*
* @throws IOException if the copying fails.
*/
public void copyFile(String sourceFile, String destFile,
FilterSetCollection filters,
boolean overwrite, boolean preserveLastModified)
throws IOException {
copyFile(new File(sourceFile), new File(destFile), filters, overwrite,
preserveLastModified);
}
/**
* Convenience method to copy a file from a source to a destination specifying if token
* filtering must be used, if source files may overwrite newer destination files and the last
* modified time of destFile file should be made equal to the last modified time
* of sourceFile.
*
* @param sourceFile Name of file to copy from. Must not be null.
* @param destFile Name of file to copy to. Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param overwrite Whether or not the destination file should be overwritten if it already
* exists.
* @param preserveLastModified Whether or not the last modified time of the resulting file
* should be set to that of the source file.
* @param encoding the encoding used to read and write the files.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.5
*/
public void copyFile(String sourceFile, String destFile,
FilterSetCollection filters, boolean overwrite,
boolean preserveLastModified, String encoding) throws IOException {
copyFile(new File(sourceFile), new File(destFile), filters,
overwrite, preserveLastModified, encoding);
}
// CheckStyle:ParameterNumberCheck OFF - bc
/**
* Convenience method to copy a file from a source to a
* destination specifying if token filtering must be used, if
* filter chains must be used, if source files may overwrite
* newer destination files and the last modified time of
* destFile file should be made equal
* to the last modified time of sourceFile.
*
* @param sourceFile Name of file to copy from.
* Must not be null.
* @param destFile Name of file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
* @param encoding the encoding used to read and write the files.
* @param project the project instance.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.5
*/
public void copyFile(String sourceFile, String destFile,
FilterSetCollection filters, VectordestFile file should be made
* equal to the last modified time of sourceFile.
*
* @param sourceFile Name of file to copy from. Must not be null.
* @param destFile Name of file to copy to. Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be overwritten if it already
* exists.
* @param preserveLastModified Whether or not the last modified time of the resulting file
* should be set to that of the source file.
* @param inputEncoding the encoding used to read the files.
* @param outputEncoding the encoding used to write the files.
* @param project the project instance.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.6
*/
public void copyFile(String sourceFile, String destFile,
FilterSetCollection filters, Vectornull.
* @param destFile the file to copy to. Must not be null.
*
* @throws IOException if the copying fails.
*/
public void copyFile(File sourceFile, File destFile) throws IOException {
copyFile(sourceFile, destFile, null, false, false);
}
/**
* Convenience method to copy a file from a source to a destination
* specifying if token filtering must be used.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
*
* @throws IOException if the copying fails.
*/
public void copyFile(File sourceFile, File destFile, FilterSetCollection filters)
throws IOException {
copyFile(sourceFile, destFile, filters, false, false);
}
/**
* Convenience method to copy a file from a source to a
* destination specifying if token filtering must be used and if
* source files may overwrite newer destination files.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
*
* @throws IOException if the copying fails.
*/
public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
boolean overwrite) throws IOException {
copyFile(sourceFile, destFile, filters, overwrite, false);
}
/**
* Convenience method to copy a file from a source to a
* destination specifying if token filtering must be used, if
* source files may overwrite newer destination files and the
* last modified time of destFile file should be made equal
* to the last modified time of sourceFile.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
*
* @throws IOException if the copying fails.
*/
public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
boolean overwrite, boolean preserveLastModified) throws IOException {
copyFile(sourceFile, destFile, filters, overwrite, preserveLastModified, null);
}
/**
* Convenience method to copy a file from a source to a destination specifying if token
* filtering must be used, if source files may overwrite newer destination files, the last
* modified time of destFile file should be made equal to the last modified time
* of sourceFile and which character encoding to assume.
*
* @param sourceFile the file to copy from. Must not be null.
* @param destFile the file to copy to. Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param overwrite Whether or not the destination file should be overwritten if it already
* exists.
* @param preserveLastModified Whether or not the last modified time of the resulting file
* should be set to that of the source file.
* @param encoding the encoding used to read and write the files.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.5
*/
public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, boolean overwrite,
boolean preserveLastModified, String encoding) throws IOException {
copyFile(sourceFile, destFile, filters, null, overwrite,
preserveLastModified, encoding, null);
}
/**
* Convenience method to copy a file from a source to a
* destination specifying if token filtering must be used, if
* filter chains must be used, if source files may overwrite
* newer destination files and the last modified time of
* destFile file should be made equal
* to the last modified time of sourceFile.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
* @param encoding the encoding used to read and write the files.
* @param project the project instance.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.5
*/
public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, VectordestFile file should be made equal
* to the last modified time of sourceFile.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
* @param inputEncoding the encoding used to read the files.
* @param outputEncoding the encoding used to write the files.
* @param project the project instance.
*
*
* @throws IOException if the copying fails.
*
* @since Ant 1.6
*/
public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, VectordestFile file should be made equal
* to the last modified time of sourceFile.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
* @param append whether to append to the destination file.
* @param inputEncoding the encoding used to read the files.
* @param outputEncoding the encoding used to write the files.
* @param project the project instance.
*
*
* @throws IOException if the copying fails.
*
* @since Ant 1.8
*/
public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, VectordestFile file should be made equal
* to the last modified time of sourceFile.
*
* @param sourceFile the file to copy from.
* Must not be null.
* @param destFile the file to copy to.
* Must not be null.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
* @param append whether to append to the destination file.
* @param inputEncoding the encoding used to read the files.
* @param outputEncoding the encoding used to write the files.
* @param project the project instance.
* @param force whether to overwrite read-only destination files.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.8.2
*/
public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, Vectornew File(file, filename) in that
* the resulting File's path will always be a normalized,
* absolute pathname. Also, if it is determined that
* filename is context-relative, file
* will be discarded and the reference will be resolved using
* available context/state information about the filesystem.
*
* @param file the "reference" file for relative paths. This
* instance must be an absolute file and must not contain
* "./" or "../" sequences (same for \ instead
* of /). If it is null, this call is equivalent to
* new java.io.File(filename).getAbsoluteFile().
*
* @param filename a file name.
*
* @return an absolute file.
* @throws java.lang.NullPointerException if filename is null.
*/
public File resolveFile(File file, String filename) {
if (!isAbsolutePath(filename)) {
char sep = File.separatorChar;
filename = filename.replace('/', sep).replace('\\', sep);
if (isContextRelativePath(filename)) {
file = null;
// on cygwin, our current directory can be a UNC;
// assume user.dir is absolute or all hell breaks loose...
String udir = System.getProperty("user.dir");
if (filename.charAt(0) == sep && udir.charAt(0) == sep) {
filename = dissect(udir)[0] + filename.substring(1);
}
}
filename = new File(file, filename).getAbsolutePath();
}
return normalize(filename);
}
/**
* On DOS and NetWare, the evaluation of certain file
* specifications is context-dependent. These are filenames
* beginning with a single separator (relative to current root directory)
* and filenames with a drive specification and no intervening separator
* (relative to current directory of the specified root).
* @param filename the filename to evaluate.
* @return true if the filename is relative to system context.
* @throws java.lang.NullPointerException if filename is null.
* @since Ant 1.7
*/
public static boolean isContextRelativePath(String filename) {
if (!(ON_DOS || ON_NETWARE) || filename.isEmpty()) {
return false;
}
char sep = File.separatorChar;
filename = filename.replace('/', sep).replace('\\', sep);
char c = filename.charAt(0);
int len = filename.length();
return (c == sep && (len == 1 || filename.charAt(1) != sep))
|| (Character.isLetter(c) && len > 1
&& filename.charAt(1) == ':'
&& (len == 2 || filename.charAt(2) != sep));
}
/**
* Verifies that the specified filename represents an absolute path.
* Differs from new java.io.File("filename").isAbsolute() in that a path
* beginning with a double file separator--signifying a Windows UNC--must
* at minimum match "\\a\b" to be considered an absolute path.
* @param filename the filename to be checked.
* @return true if the filename represents an absolute path.
* @throws java.lang.NullPointerException if filename is null.
* @since Ant 1.6.3
*/
public static boolean isAbsolutePath(String filename) {
if (filename.isEmpty()) {
return false;
}
int len = filename.length();
char sep = File.separatorChar;
filename = filename.replace('/', sep).replace('\\', sep);
char c = filename.charAt(0);
if (!ON_DOS && !ON_NETWARE) {
return c == sep;
}
if (c == sep) {
// CheckStyle:MagicNumber OFF
if (!ON_DOS || len <= 4 || filename.charAt(1) != sep) {
return false;
}
// CheckStyle:MagicNumber ON
int nextsep = filename.indexOf(sep, 2);
return nextsep > 2 && nextsep + 1 < len;
}
int colon = filename.indexOf(':');
return (Character.isLetter(c) && colon == 1
&& filename.length() > 2 && filename.charAt(2) == sep)
|| (ON_NETWARE && colon > 0);
}
/**
* Translate a path into its native (platform specific) format.
*
* This method uses PathTokenizer to separate the input path
* into its components. This handles DOS style paths in a relatively
* sensible way. The file separators are then converted to their platform
* specific versions.
*
* @param toProcess The path to be translated.
* May be null.
*
* @return the native version of the specified path or
* an empty string if the path is null or empty.
*
* @since ant 1.7
* @see PathTokenizer
*/
public static String translatePath(String toProcess) {
if (toProcess == null || toProcess.isEmpty()) {
return "";
}
StringBuilder path = new StringBuilder(toProcess.length() + EXPAND_SPACE);
PathTokenizer tokenizer = new PathTokenizer(toProcess);
while (tokenizer.hasMoreTokens()) {
String pathComponent = tokenizer.nextToken();
pathComponent = pathComponent.replace('/', File.separatorChar);
pathComponent = pathComponent.replace('\\', File.separatorChar);
if (path.length() > 0) {
path.append(File.pathSeparatorChar);
}
path.append(pathComponent);
}
return path.toString();
}
/**
* "Normalize" the given absolute path.
*
*
This includes: *
Unlike {@link File#getCanonicalPath()} this method * specifically does not resolve symbolic links.
* *If the path tries to go beyond the file system root (i.e. it * contains more ".." segments than can be travelled up) the * method will return the original path unchanged.
* * @param path the path to be normalized. * @return the normalized version of the path. * * @throws java.lang.NullPointerException if path is null. */ public File normalize(final String path) { StackFile object.
* This is useful since the JVM by default internally converts VMS paths
* to Unix style.
* The returned String is always an absolute path.
*
* @param f The File to get the VMS path for.
* @return The absolute VMS path to f.
*/
public String toVMSPath(File f) {
// format: "DEVICE:[DIR.SUBDIR]FILE"
String osPath;
String path = normalize(f.getAbsolutePath()).getPath();
String name = f.getName();
boolean isAbsolute = path.charAt(0) == File.separatorChar;
// treat directories specified using .DIR syntax as files
// CheckStyle:MagicNumber OFF
boolean isDirectory = f.isDirectory()
&& !name.regionMatches(true, name.length() - 4, ".DIR", 0, 4);
// CheckStyle:MagicNumber ON
String device = null;
StringBuilder directory = null;
String file = null;
int index = 0;
if (isAbsolute) {
index = path.indexOf(File.separatorChar, 1);
if (index == -1) {
return path.substring(1) + ":[000000]";
}
device = path.substring(1, index++);
}
if (isDirectory) {
directory = new StringBuilder(path.substring(index).replace(File.separatorChar, '.'));
} else {
int dirEnd = path.lastIndexOf(File.separatorChar);
if (dirEnd == -1 || dirEnd < index) {
file = path.substring(index);
} else {
directory = new StringBuilder(path.substring(index, dirEnd)
.replace(File.separatorChar, '.'));
index = dirEnd + 1;
if (path.length() > index) {
file = path.substring(index);
}
}
}
if (!isAbsolute && directory != null) {
directory.insert(0, '.');
}
osPath = ((device != null) ? device + ":" : "")
+ ((directory != null) ? "[" + directory + "]" : "")
+ ((file != null) ? file : "");
return osPath;
}
/**
* Create a File object for a temporary file in a given directory. Without
* actually creating the file.
*
* * The file denoted by the returned abstract pathname did not exist before * this method was invoked, any subsequent invocation of this method will * yield a different file name. *
* *If the filesystem where the temporary file is created * supports POSIX permissions, the file will only be readable and * writable by the current user.
* * @param prefix file name prefix. * @param suffix * file extension; include the '.'. * @param parentDir * Directory to create the temporary file in; java.io.tmpdir used * if not specified. * * @deprecated since ant 1.7.1 use createTempFile(Project, String, String, File, * boolean, boolean) instead. * @return a File reference to the new, nonexistent temporary file. */ @Deprecated public File createTempFile(String prefix, String suffix, File parentDir) { return createTempFile(prefix, suffix, parentDir, false, false); } /** * Create a temporary file in a given directory. * *The file denoted by the returned abstract pathname did not * exist before this method was invoked, any subsequent invocation * of this method will yield a different file name.
* *If the filesystem where the temporary file is created * supports POSIX permissions, the file will only be readable and * writable by the current user.
* * @param prefix file name prefix. * @param suffix file extension; include the '.'. * @param parentDir Directory to create the temporary file in; * java.io.tmpdir used if not specified. * @param deleteOnExit whether to set the tempfile for deletion on * normal VM exit. * @param createFile true if the file must actually be created. If false * chances exist that a file with the same name is created in the time * between invoking this method and the moment the file is actually created. * If possible set to true. * * @return a File reference to the new temporary file. * @since Ant 1.7.1 * @deprecated since Ant 1.10.8 use createTempFile(Project, String, String, File, * boolean, boolean) instead. */ @Deprecated public File createTempFile(String prefix, String suffix, File parentDir, boolean deleteOnExit, boolean createFile) { return createTempFile(null, prefix, suffix, parentDir, deleteOnExit, createFile); } private static final String NULL_PLACEHOLDER = "null"; /** * Create a temporary file in a given directory. * *The file denoted by the returned abstract pathname did not * exist before this method was invoked, any subsequent invocation * of this method will yield a different file name.
* *If the filesystem where the temporary file is created * supports POSIX permissions, the file will only be readable and * writable by the current user.
* * @param project reference to the current Ant project. * @param prefix file name prefix. * @param suffix file extension; include the '.'. * @param parentDir Directory to create the temporary file in; * if not specified and {@code project} is not null then the value * of the property {@code ant.tmpdir} is used if set; * otherwise {@code java.io.tmpdir} is used. * @param deleteOnExit whether to set the tempfile for deletion on * normal VM exit. * @param createFile true if the file must actually be created. If false * chances exist that a file with the same name is created in the time * between invoking this method and the moment the file is actually created. * If possible set to true. * * @return a File reference to the new temporary file. * @since Ant 1.9.15 */ public File createTempFile(final Project project, String prefix, String suffix, final File parentDir, final boolean deleteOnExit, final boolean createFile) { File result; String p = null; if (parentDir != null) { p = parentDir.getPath(); } else if (project != null && project.getProperty(MagicNames.TMPDIR) != null) { p = project.getProperty(MagicNames.TMPDIR); } else if (project != null && deleteOnExit) { if (project.getProperty(MagicNames.AUTO_TMPDIR) != null) { p = project.getProperty(MagicNames.AUTO_TMPDIR); } else { final Path systemTempDirPath = new File(System.getProperty("java.io.tmpdir")).toPath(); final PosixFileAttributeView systemTempDirPosixAttributes = Files.getFileAttributeView(systemTempDirPath, PosixFileAttributeView.class); if (systemTempDirPosixAttributes != null) { // no reason to create an extra temp dir if we cannot set permissions try { final File projectTempDir = Files.createTempDirectory(systemTempDirPath, "ant", TMPDIR_ATTRIBUTES) .toFile(); projectTempDir.deleteOnExit(); p = projectTempDir.getAbsolutePath(); project.setProperty(MagicNames.AUTO_TMPDIR, p); } catch (IOException ex) { // silently fall back to system temp directory } } } } final String parent = p != null ? p : System.getProperty("java.io.tmpdir"); if (prefix == null) { prefix = NULL_PLACEHOLDER; } if (suffix == null) { suffix = NULL_PLACEHOLDER; } if (createFile) { try { final Path parentPath = new File(parent).toPath(); final PosixFileAttributeView parentPosixAttributes = Files.getFileAttributeView(parentPath, PosixFileAttributeView.class); result = Files.createTempFile(parentPath, prefix, suffix, parentPosixAttributes != null ? TMPFILE_ATTRIBUTES : NO_TMPFILE_ATTRIBUTES) .toFile(); } catch (IOException e) { throw new BuildException("Could not create tempfile in " + parent, e); } } else { DecimalFormat fmt = new DecimalFormat("#####"); synchronized (rand) { do { result = new File(parent, prefix + fmt.format(rand.nextInt(Integer.MAX_VALUE)) + suffix); } while (result.exists()); } } if (deleteOnExit) { result.deleteOnExit(); } return result; } /** * Create a File object for a temporary file in a given directory. Without * actually creating the file. * ** The file denoted by the returned abstract pathname did not exist before * this method was invoked, any subsequent invocation of this method will * yield a different file name. *
* *If the filesystem where the temporary file is created * supports POSIX permissions, the file will only be readable and * writable by the current user.
* * @param prefix file name prefix. * @param suffix * file extension; include the '.'. * @param parentDir * Directory to create the temporary file in; java.io.tmpdir used * if not specified. * @param deleteOnExit * whether to set the tempfile for deletion on normal VM exit. * * @deprecated since ant 1.7.1 use createTempFile(Project, String, String, File, * boolean, boolean) instead. * @return a File reference to the new, nonexistent temporary file. */ @Deprecated public File createTempFile(String prefix, String suffix, File parentDir, boolean deleteOnExit) { return createTempFile(prefix, suffix, parentDir, deleteOnExit, false); } /** * Compares the contents of two files. * * @param f1 the file whose content is to be compared. * @param f2 the other file whose content is to be compared. * * @return true if the content of the files is the same. * * @throws IOException if the files cannot be read. */ public boolean contentEquals(File f1, File f2) throws IOException { return contentEquals(f1, f2, false); } /** * Compares the contents of two files. * * @param f1 the file whose content is to be compared. * @param f2 the other file whose content is to be compared. * @param textfile true if the file is to be treated as a text file and * differences in kind of line break are to be ignored. * * @return true if the content of the files is the same. * * @throws IOException if the files cannot be read. * @since Ant 1.6.3 */ public boolean contentEquals(File f1, File f2, boolean textfile) throws IOException { return ResourceUtils.contentEquals(new FileResource(f1), new FileResource(f2), textfile); } /** * This was originally an emulation of {@link File#getParentFile} for JDK 1.1, but it is now * implemented using that method (Ant 1.6.3 onwards). * * @param f the file whose parent is required. * @return the given file's parent, or null if the file does not have a parent. * @since 1.10 * @deprecated since 1.7. Just use {@link File#getParentFile} directly. */ @Deprecated public File getParentFile(File f) { return f == null ? null : f.getParentFile(); } /** * Read from reader till EOF. * @param rdr the reader from which to read. * @return the contents read out of the given reader. * * @throws IOException if the contents could not be read out from the * reader. */ public static String readFully(Reader rdr) throws IOException { return readFully(rdr, BUF_SIZE); } /** * Read from reader till EOF. * * @param rdr the reader from which to read. * @param bufferSize the buffer size to use when reading. * * @return the contents read out of the given reader. * * @throws IOException if the contents could not be read out from the * reader. */ public static String readFully(Reader rdr, int bufferSize) throws IOException { if (bufferSize <= 0) { throw new IllegalArgumentException( "Buffer size must be greater than 0"); } final char[] buffer = new char[bufferSize]; int bufferLength = 0; StringBuilder textBuffer = new StringBuilder(); while (bufferLength != -1) { bufferLength = rdr.read(buffer); if (bufferLength > 0) { textBuffer.append(buffer, 0, bufferLength); } } return (textBuffer.length() == 0) ? null : textBuffer.toString(); } /** * Safe read fully - do not return a null for an empty reader. * @param reader the input to read from. * @return the string. * @throws IOException if unable to read from reader. * @since Ant 1.7.1 */ public static String safeReadFully(Reader reader) throws IOException { String ret = readFully(reader); return ret == null ? "" : ret; } /** * This was originally an emulation of File.createNewFile for JDK 1.1, * but it is now implemented using that method (Ant 1.6.3 onwards). * *This method has historically not guaranteed that the
* operation was atomic. In its current implementation it is.
*
* @param f the file to be created.
* @return true if the file did not exist already.
* @throws IOException on error.
* @since Ant 1.5
*/
public boolean createNewFile(File f) throws IOException {
return f.createNewFile();
}
/**
* Create a new file, optionally creating parent directories.
*
* @param f the file to be created.
* @param mkdirs boolean whether to create parent directories.
* @return true if the file did not exist already.
* @throws IOException on error.
* @since Ant 1.6.3
*/
public boolean createNewFile(File f, boolean mkdirs) throws IOException {
File parent = f.getParentFile();
if (mkdirs && !(parent.exists())) {
parent.mkdirs();
}
return f.createNewFile();
}
/**
* Checks whether a given file is a symbolic link.
*
*
It doesn't really test for symbolic links but whether the * canonical and absolute paths of the file are identical--this * may lead to false positives on some platforms.
* * @param parent the parent directory of the file to test * @param name the name of the file to test. * * @return true if the file is a symbolic link. * @throws IOException on error. * @since Ant 1.5 * @deprecated use {@link Files#isSymbolicLink(Path)} instead */ @Deprecated public boolean isSymbolicLink(final File parent, final String name) throws IOException { if (parent == null) { return Files.isSymbolicLink(Paths.get(name)); } return Files.isSymbolicLink(Paths.get(parent.toPath().toString(), name)); } /** * Removes a leading path from a second path. * *This method uses {@link #normalize} under the covers and * does not resolve symbolic links.
* * @param leading The leading path, must not be null, must be absolute. * @param path The path to remove from, must not be null, must be absolute. * * @return path's normalized absolute if it doesn't start with * leading; path's path with leading's path removed otherwise. * * @since Ant 1.5 */ public String removeLeadingPath(File leading, File path) { String l = normalize(leading.getAbsolutePath()).getAbsolutePath(); String p = normalize(path.getAbsolutePath()).getAbsolutePath(); if (l.equals(p)) { return ""; } // ensure that l ends with a / // so we never think /foo was a parent directory of /foobar if (!l.endsWith(File.separator)) { l += File.separator; } return (p.startsWith(l)) ? p.substring(l.length()) : p; } /** * Learn whether one path "leads" another. * *This method uses {@link #normalize} under the covers and * does not resolve symbolic links.
* *If either path tries to go beyond the file system root * (i.e. it contains more ".." segments than can be travelled up) * the method will return false.
* * @param leading The leading path, must not be null, must be absolute. * @param path The path to check, must not be null, must be absolute. * @return true if path starts with leading; false otherwise. * @since Ant 1.7 */ public boolean isLeadingPath(File leading, File path) { String l = normalize(leading.getAbsolutePath()).getAbsolutePath(); String p = normalize(path.getAbsolutePath()).getAbsolutePath(); if (l.equals(p)) { return true; } // ensure that l ends with a / // so we never think /foo was a parent directory of /foobar if (!l.endsWith(File.separator)) { l += File.separator; } // ensure "/foo/" is not considered a parent of "/foo/../../bar" String up = File.separator + ".." + File.separator; if (l.contains(up) || p.contains(up) || (p + File.separator).contains(up)) { return false; } return p.startsWith(l); } /** * Learn whether one path "leads" another. * * @param leading The leading path, must not be null, must be absolute. * @param path The path to check, must not be null, must be absolute. * @param resolveSymlinks whether symbolic links shall be resolved * prior to comparing the paths. * @return true if path starts with leading; false otherwise. * @since Ant 1.10.5 * @throws IOException if resolveSymlinks is true and invoking * getCanonicaPath on either argument throws an exception */ public boolean isLeadingPath(File leading, File path, boolean resolveSymlinks) throws IOException { if (!resolveSymlinks) { return isLeadingPath(leading, path); } final File l = leading.getCanonicalFile(); File p = path.getCanonicalFile(); do { if (l.equals(p)) { return true; } p = p.getParentFile(); } while (p != null); return false; } /** * Constructs afile: URI that represents the
* external form of the given pathname.
*
* Will be an absolute URI if the given path is absolute.
* *This code encodes non ASCII characters too.
* *The coding of the output is the same as what File.toURI().toASCIIString() produces
* * See dt-sysid * which makes some mention of how * characters not supported by URI Reference syntax should be escaped. * * @param path the path in the local file system. * @return the URI version of the local path. * @since Ant 1.6 */ public String toURI(String path) { return new File(path).toURI().toASCIIString(); } /** * Constructs a file path from afile: URI.
*
* Will be an absolute path if the given URI is absolute.
* *Swallows '%' that are not followed by two characters, * doesn't deal with non-ASCII characters.
* * @param uri the URI designating a file in the local filesystem. * @return the local file system path for the file. * @since Ant 1.6 */ public String fromURI(String uri) { synchronized (cacheFromUriLock) { if (uri.equals(cacheFromUriRequest)) { return cacheFromUriResponse; } String path = Locator.fromURI(uri); String ret = isAbsolutePath(path) ? normalize(path).getAbsolutePath() : path; cacheFromUriRequest = uri; cacheFromUriResponse = ret; return ret; } } /** * Compares two filenames. * *Unlike java.io.File#equals this method will try to compare * the absolute paths and "normalize" the filenames * before comparing them.
* * @param f1 the file whose name is to be compared. * @param f2 the other file whose name is to be compared. * * @return true if the file are for the same file. * * @since Ant 1.5.3 */ public boolean fileNameEquals(File f1, File f2) { return normalize(f1.getAbsolutePath()).getAbsolutePath().equals( normalize(f2.getAbsolutePath()).getAbsolutePath()); } /** * Are the two File instances pointing to the same object on the * file system? * * @param f1 File * @param f2 File * @return boolean * @throws IOException if file name canonicalization fails * @since Ant 1.8.2 */ public boolean areSame(File f1, File f2) throws IOException { if (f1 == null && f2 == null) { return true; } if (f1 == null || f2 == null) { return false; } return fileNameEquals(f1, f2) || isSameFile(f1, f2); } private boolean isSameFile(File f1, File f2) throws IOException { if (f1.exists()) { try { return f2.exists() && Files.isSameFile(f1.toPath(), f2.toPath()); } catch (NoSuchFileException e) { // file has been removed between exists check and isSameFile? return false; } } File f1Normalized = normalize(f1.getAbsolutePath()); File f2Normalized = normalize(f2.getAbsolutePath()); return f1Normalized.getCanonicalFile().equals(f2Normalized .getCanonicalFile()); } /** * Renames a file, even if that involves crossing file system boundaries. * *This will remove to (if it exists), ensure that
* to's parent directory exists and move
* from, which involves deleting from as
* well.
to may have been deleted
* already when this happens.
* @since Ant 1.6
*/
public void rename(File from, File to) throws IOException {
// identical logic lives in Move.renameFile():
from = normalize(from.getAbsolutePath()).getCanonicalFile();
to = normalize(to.getAbsolutePath());
if (!from.exists()) {
System.err.println("Cannot rename nonexistent file " + from);
return;
}
if (from.getAbsolutePath().equals(to.getAbsolutePath())) {
System.err.println("Rename of " + from + " to " + to + " is a no-op.");
return;
}
if (to.exists() && !(areSame(from, to) || tryHardToDelete(to))) {
throw new IOException("Failed to delete " + to + " while trying to rename " + from);
}
File parent = to.getParentFile();
if (parent != null && !parent.isDirectory()
&& !(parent.mkdirs() || parent.isDirectory())) {
throw new IOException("Failed to create directory " + parent
+ " while trying to rename " + from);
}
if (!from.renameTo(to)) {
copyFile(from, to);
if (!tryHardToDelete(from)) {
throw new IOException("Failed to delete " + from + " while trying to rename it.");
}
}
}
/**
* Get the granularity of file timestamps. The choice is made based on OS, which is
* incorrect--it should really be by filesystem. We do not have an easy way to probe for file
* systems, however, so this heuristic gives us a decent default.
*
* @return the difference, in milliseconds, which two file timestamps must have in order for the
* two files to be considered to have different timestamps.
*/
public long getFileTimestampGranularity() {
if (ON_WIN9X) {
return FAT_FILE_TIMESTAMP_GRANULARITY;
}
if (ON_WINDOWS) {
return NTFS_FILE_TIMESTAMP_GRANULARITY;
}
if (ON_DOS) {
return FAT_FILE_TIMESTAMP_GRANULARITY;
}
return UNIX_FILE_TIMESTAMP_GRANULARITY;
}
/**
* test whether a file or directory exists, with an error in the
* upper/lower case spelling of the name.
* Using this method is only interesting on case insensitive file systems
* (Windows).
* * It will return true only if 3 conditions are met: *
** The purpose is to identify files or directories on case-insensitive * filesystems whose case is not what is expected. *
* Possibly to rename them afterwards to the desired upper/lowercase * combination. * * @param localFile file to test * @return true if the file exists and the case of the actual file * is not the case of the parameter * @since Ant 1.7.1 */ public boolean hasErrorInCase(File localFile) { localFile = normalize(localFile.getAbsolutePath()); if (!localFile.exists()) { return false; } final String localFileName = localFile.getName(); FilenameFilter ff = (dir, name) -> name.equalsIgnoreCase(localFileName) && (!name.equals(localFileName)); String[] names = localFile.getParentFile().list(ff); return names != null && names.length == 1; } /** * Returns true if the source is older than the dest. * If the dest file does not exist, then the test returns false; it is * implicitly not up do date. * @param source source file (should be the older). * @param dest dest file (should be the newer). * @param granularity an offset added to the source time. * @return true if the source is older than the dest after accounting * for granularity. * @since Ant 1.6.3 */ public boolean isUpToDate(File source, File dest, long granularity) { //do a check for the destination file existing if (!dest.exists()) { //if it does not, then the file is not up to date. return false; } long sourceTime = source.lastModified(); long destTime = dest.lastModified(); return isUpToDate(sourceTime, destTime, granularity); } /** * Returns true if the source is older than the dest. * @param source source file (should be the older). * @param dest dest file (should be the newer). * @return true if the source is older than the dest, taking the granularity into account. * @since Ant 1.6.3 */ public boolean isUpToDate(File source, File dest) { return isUpToDate(source, dest, getFileTimestampGranularity()); } /** * Compare two timestamps for being up to date using * the specified granularity. * * @param sourceTime timestamp of source file. * @param destTime timestamp of dest file. * @param granularity os/filesys granularity. * @return true if the dest file is considered up to date. */ public boolean isUpToDate(long sourceTime, long destTime, long granularity) { return destTime != -1 && destTime >= sourceTime + granularity; } /** * Compare two timestamps for being up to date using the * current granularity. * * @param sourceTime timestamp of source file. * @param destTime timestamp of dest file. * @return true if the dest file is considered up to date. */ public boolean isUpToDate(long sourceTime, long destTime) { return isUpToDate(sourceTime, destTime, getFileTimestampGranularity()); } /** * Close a Writer without throwing any exception if something went wrong. * Do not attempt to close it if the argument is null. * @param device output writer, can be null. */ public static void close(Writer device) { close((AutoCloseable) device); } /** * Close a Reader without throwing any exception if something went wrong. * Do not attempt to close it if the argument is null. * * @param device Reader, can be null. */ public static void close(Reader device) { close((AutoCloseable) device); } /** * Close a stream without throwing any exception if something went wrong. * Do not attempt to close it if the argument is null. * * @param device stream, can be null. */ public static void close(OutputStream device) { close((AutoCloseable) device); } /** * Close a stream without throwing any exception if something went wrong. * Do not attempt to close it if the argument is null. * * @param device stream, can be null. */ public static void close(InputStream device) { close((AutoCloseable) device); } /** * Close a Channel without throwing any exception if something went wrong. * Do not attempt to close it if the argument is null. * * @param device channel, can be null. * @since Ant 1.8.0 */ public static void close(Channel device) { close((AutoCloseable) device); } /** * Closes an URLConnection if its concrete implementation provides * a way to close it that Ant knows of. * * @param conn connection, can be null * @since Ant 1.8.0 */ public static void close(URLConnection conn) { if (conn != null) { try { if (conn instanceof JarURLConnection) { JarURLConnection juc = (JarURLConnection) conn; JarFile jf = juc.getJarFile(); jf.close(); } else if (conn instanceof HttpURLConnection) { ((HttpURLConnection) conn).disconnect(); } } catch (IOException exc) { //ignore } } } /** * Close an {@link AutoCloseable} without throwing any exception * if something went wrong. Do not attempt to close it if the * argument is null. * * @param ac AutoCloseable, can be null. * @since Ant 1.10.0 */ public static void close(AutoCloseable ac) { if (null != ac) { try { ac.close(); } catch (Exception e) { //ignore } } } /** * Delete the file with {@link File#delete()} if the argument is not null. * Do nothing on a null argument. * @param file file to delete. */ public static void delete(File file) { if (file != null) { file.delete(); } } /** * Accommodate Windows bug encountered in both Sun and IBM JDKs. * Others possible. If the delete does not work, call System.gc(), * wait a little and try again. * * @param f File * @return whether deletion was successful * @since Ant 1.8.0 */ public boolean tryHardToDelete(File f) { return tryHardToDelete(f, ON_WINDOWS); } /** * If delete does not work, call System.gc() if asked to, wait a * little and try again. * * @param f File * @param runGC boolean * @return whether deletion was successful * @since Ant 1.8.3 */ public boolean tryHardToDelete(File f, boolean runGC) { if (!f.delete()) { if (runGC) { System.gc(); } try { Thread.sleep(DELETE_RETRY_SLEEP_MILLIS); } catch (InterruptedException ex) { // Ignore Exception } return f.delete(); } return true; } /** * Calculates the relative path between two files. *
* Implementation note:
This function may throw an IOException if an I/O error occurs
* because its use of the canonical pathname may require filesystem queries.
*
File to calculate the path from
* @param toFile the File to calculate the path to
* @return the relative path between the files
* @throws Exception for undocumented reasons
* @see File#getCanonicalPath()
*
* @since Ant 1.7
*/
public static String getRelativePath(File fromFile, File toFile) throws Exception { //NOSONAR
String fromPath = fromFile.getCanonicalPath();
String toPath = toFile.getCanonicalPath();
// build the path stack info to compare
String[] fromPathStack = getPathStack(fromPath);
String[] toPathStack = getPathStack(toPath);
if (0 < toPathStack.length && 0 < fromPathStack.length) {
if (!fromPathStack[0].equals(toPathStack[0])) {
// not the same device (would be "" on Linux/Unix)
return getPath(Arrays.asList(toPathStack));
}
} else {
// no comparison possible
return getPath(Arrays.asList(toPathStack));
}
// get index of parts which are equal
int minLength = Math.min(fromPathStack.length, toPathStack.length);
int same = 1;
while (same < minLength && fromPathStack[same].equals(toPathStack[same])) {
same++;
}
ListStrings.
*
* @param path to get names from
* @return Strings, never null
*
* @since Ant 1.7
*/
public static String[] getPathStack(String path) {
String normalizedPath = path.replace(File.separatorChar, '/');
return normalizedPath.split("/");
}
/**
* Gets path from a List of Strings.
*
* @param pathStack List of Strings to be concatenated as a path.
* @return String, never null
*
* @since Ant 1.7
*/
public static String getPath(ListList of Strings.
*
* @param pathStack List of Strings to be concatenated as a path.
* @param separatorChar char to be used as separator between names in path
* @return String, never null
*
* @since Ant 1.7
*/
public static String getPath(final List* This method works on a best effort basis and will return an {@link Optional#empty()} * if it cannot determine the case sensitivity, either due to exception or for any other * reason. *
* @param path The path whose filesystem case sensitivity needs to be checked * @return Returns true if the filesystem corresponding to the passed {@code path} * is case sensitive. Else returns false. If the case sensitivity * cannot be determined for whatever reason, this method returns an * {@link Optional#empty()} * @throws IllegalArgumentException If the passed path is null * @since Ant 1.10.6 */ public static Optional