aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/apache/commons/io/FileUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/apache/commons/io/FileUtils.java')
-rw-r--r--src/main/java/org/apache/commons/io/FileUtils.java119
1 files changed, 63 insertions, 56 deletions
diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java
index 807dc37c..80d100f1 100644
--- a/src/main/java/org/apache/commons/io/FileUtils.java
+++ b/src/main/java/org/apache/commons/io/FileUtils.java
@@ -36,6 +36,7 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.nio.file.CopyOption;
+import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@@ -108,7 +109,7 @@ import org.apache.commons.io.function.Uncheck;
* {@link SecurityException} are not documented in the Javadoc.
* </p>
* <p>
- * Origin of code: Excalibur, Alexandria, Commons-Utils
+ * Provenance: Excalibur, Alexandria, Commons-Utils
* </p>
*/
public class FileUtils {
@@ -352,16 +353,13 @@ public class FileUtils {
* This method checks to see if the two files are different lengths or if they point to the same file, before
* resorting to byte-by-byte comparison of the contents.
* </p>
- * <p>
- * Code origin: Avalon
- * </p>
*
* @param file1 the first file
* @param file2 the second file
* @return true if the content of the files are equal or they both don't exist, false otherwise
* @throws IllegalArgumentException when an input is not a file.
* @throws IOException If an I/O error occurs.
- * @see org.apache.commons.io.file.PathUtils#fileContentEquals(Path,Path,java.nio.file.LinkOption[],java.nio.file.OpenOption...)
+ * @see PathUtils#fileContentEquals(Path,Path)
*/
public static boolean contentEquals(final File file1, final File file2) throws IOException {
if (file1 == null && file2 == null) {
@@ -393,9 +391,7 @@ public class FileUtils {
return true;
}
- try (InputStream input1 = Files.newInputStream(file1.toPath()); InputStream input2 = Files.newInputStream(file2.toPath())) {
- return IOUtils.contentEquals(input1, input2);
- }
+ return PathUtils.fileContentEquals(file1.toPath(), file2.toPath());
}
/**
@@ -451,12 +447,12 @@ public class FileUtils {
}
/**
- * Converts a Collection containing java.io.File instances into array
+ * Converts a Collection containing {@link File} instances into array
* representation. This is to account for the difference between
* File.listFiles() and FileUtils.listFiles().
*
- * @param files a Collection containing java.io.File instances
- * @return an array of java.io.File
+ * @param files a Collection containing {@link File} instances
+ * @return an array of {@link File}
*/
public static File[] convertFileCollectionToFileArray(final Collection<File> files) {
return files.toArray(EMPTY_FILE_ARRAY);
@@ -1449,7 +1445,7 @@ public class FileUtils {
/**
* Returns a {@link File} representing the system temporary directory.
*
- * @return the system temporary directory.
+ * @return the system temporary directory as a File
* @since 2.0
*/
public static File getTempDirectory() {
@@ -1459,7 +1455,12 @@ public class FileUtils {
/**
* Returns the path to the system temporary directory.
*
- * @return the path to the system temporary directory.
+ * WARNING: this method relies on the Java system property 'java.io.tmpdir'
+ * which may or may not have a trailing file separator.
+ * This can affect code that uses String processing to manipulate pathnames rather
+ * than the standard libary methods in classes such as {@link java.io.File}
+ *
+ * @return the path to the system temporary directory as a String
* @since 2.0
*/
public static String getTempDirectoryPath() {
@@ -1971,7 +1972,7 @@ public class FileUtils {
* @param dirFilter optional filter to apply when finding subdirectories.
* If this parameter is {@code null}, subdirectories will not be included in the
* search. Use TrueFileFilter.INSTANCE to match all directories.
- * @return an iterator of java.io.File for the matching files
+ * @return an iterator of {@link File} for the matching files
* @see org.apache.commons.io.filefilter.FileFilterUtils
* @see org.apache.commons.io.filefilter.NameFileFilter
* @since 1.2
@@ -1988,14 +1989,14 @@ public class FileUtils {
* </p>
*
* @param directory the directory to search in
- * @param extensions an array of extensions, ex. {"java","xml"}. If this
+ * @param extensions an array of extensions, for example, {"java","xml"}. If this
* parameter is {@code null}, all files are returned.
* @param recursive if true all subdirectories are searched as well
- * @return an iterator of java.io.File with the matching files
+ * @return an iterator of {@link File} with the matching files
* @since 1.2
*/
public static Iterator<File> iterateFiles(final File directory, final String[] extensions, final boolean recursive) {
- return Uncheck.apply(d -> streamFiles(d, recursive, extensions).iterator(), directory);
+ return StreamIterator.iterator(Uncheck.get(() -> streamFiles(directory, recursive, extensions)));
}
/**
@@ -2016,7 +2017,7 @@ public class FileUtils {
* @param dirFilter optional filter to apply when finding subdirectories.
* If this parameter is {@code null}, subdirectories will not be included in the
* search. Use TrueFileFilter.INSTANCE to match all directories.
- * @return an iterator of java.io.File for the matching files
+ * @return an iterator of {@link File} for the matching files
* @see org.apache.commons.io.filefilter.FileFilterUtils
* @see org.apache.commons.io.filefilter.NameFileFilter
* @since 2.2
@@ -2216,28 +2217,30 @@ public class FileUtils {
* @param dirFilter optional filter to apply when finding subdirectories.
* If this parameter is {@code null}, subdirectories will not be included in the
* search. Use {@link TrueFileFilter#INSTANCE} to match all directories.
- * @return a collection of java.io.File with the matching files
+ * @return a collection of {@link File} with the matching files
* @see org.apache.commons.io.filefilter.FileFilterUtils
* @see org.apache.commons.io.filefilter.NameFileFilter
*/
public static Collection<File> listFiles(final File directory, final IOFileFilter fileFilter, final IOFileFilter dirFilter) {
final AccumulatorPathVisitor visitor = Uncheck
.apply(d -> listAccumulate(d, FileFileFilter.INSTANCE.and(fileFilter), dirFilter, FileVisitOption.FOLLOW_LINKS), directory);
- return visitor.getFileList().stream().map(Path::toFile).collect(Collectors.toList());
+ return toList(visitor.getFileList().stream().map(Path::toFile));
}
/**
- * Finds files within a given directory (and optionally its subdirectories)
+ * Lists files within a given directory (and optionally its subdirectories)
* which match an array of extensions.
*
* @param directory the directory to search in
- * @param extensions an array of extensions, ex. {"java","xml"}. If this
+ * @param extensions an array of extensions, for example, {"java","xml"}. If this
* parameter is {@code null}, all files are returned.
* @param recursive if true all subdirectories are searched as well
- * @return a collection of java.io.File with the matching files
+ * @return a collection of {@link File} with the matching files
*/
public static Collection<File> listFiles(final File directory, final String[] extensions, final boolean recursive) {
- return Uncheck.apply(d -> toList(streamFiles(d, recursive, extensions)), directory);
+ try (Stream<File> fileStream = Uncheck.get(() -> streamFiles(directory, recursive, extensions))) {
+ return toList(fileStream);
+ }
}
/**
@@ -2253,7 +2256,7 @@ public class FileUtils {
* @param dirFilter optional filter to apply when finding subdirectories.
* If this parameter is {@code null}, subdirectories will not be included in the
* search. Use TrueFileFilter.INSTANCE to match all directories.
- * @return a collection of java.io.File with the matching files
+ * @return a collection of {@link File} with the matching files
* @see org.apache.commons.io.FileUtils#listFiles
* @see org.apache.commons.io.filefilter.FileFilterUtils
* @see org.apache.commons.io.filefilter.NameFileFilter
@@ -2264,7 +2267,7 @@ public class FileUtils {
directory);
final List<Path> list = visitor.getFileList();
list.addAll(visitor.getDirList());
- return list.stream().map(Path::toFile).collect(Collectors.toList());
+ return toList(list.stream().map(Path::toFile));
}
/**
@@ -2570,9 +2573,8 @@ public class FileUtils {
* @param file the file to read, must not be {@code null}
* @return the file contents, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @since 1.1
*/
public static byte[] readFileToByteArray(final File file) throws IOException {
@@ -2587,9 +2589,8 @@ public class FileUtils {
* @param file the file to read, must not be {@code null}
* @return the file contents, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @since 1.3.1
* @deprecated 2.5 use {@link #readFileToString(File, Charset)} instead (and specify the appropriate encoding)
*/
@@ -2606,9 +2607,8 @@ public class FileUtils {
* @param charsetName the name of the requested charset, {@code null} means platform default
* @return the file contents, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @since 2.3
*/
public static String readFileToString(final File file, final Charset charsetName) throws IOException {
@@ -2622,9 +2622,8 @@ public class FileUtils {
* @param charsetName the name of the requested charset, {@code null} means platform default
* @return the file contents, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
* .UnsupportedEncodingException} in version 2.2 if the named charset is unavailable.
* @since 2.3
@@ -2640,9 +2639,8 @@ public class FileUtils {
* @param file the file to read, must not be {@code null}
* @return the list of Strings representing each line in the file, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @since 1.3
* @deprecated 2.5 use {@link #readLines(File, Charset)} instead (and specify the appropriate encoding)
*/
@@ -2659,9 +2657,8 @@ public class FileUtils {
* @param charset the charset to use, {@code null} means platform default
* @return the list of Strings representing each line in the file, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @since 2.3
*/
public static List<String> readLines(final File file, final Charset charset) throws IOException {
@@ -2675,9 +2672,8 @@ public class FileUtils {
* @param charsetName the name of the requested charset, {@code null} means platform default
* @return the list of Strings representing each line in the file, never {@code null}
* @throws NullPointerException if file is {@code null}.
- * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular file, or for some
- * other reason cannot be opened for reading.
- * @throws IOException if an I/O error occurs.
+ * @throws IOException if an I/O error occurs, including when the file does not exist, is a directory rather than a
+ * regular file, or for some other reason why the file cannot be opened for reading.
* @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
* .UnsupportedEncodingException} in version 2.2 if the named charset is unavailable.
* @since 1.1
@@ -2861,9 +2857,8 @@ public class FileUtils {
* {@code false} otherwise
* @throws NullPointerException if sourceFile is {@code null}.
* @throws NullPointerException if targetFile is {@code null}.
- * @throws IOException if setting the last-modified time failed.
*/
- private static boolean setTimes(final File sourceFile, final File targetFile) throws IOException {
+ private static boolean setTimes(final File sourceFile, final File targetFile) {
Objects.requireNonNull(sourceFile, "sourceFile");
Objects.requireNonNull(targetFile, "targetFile");
try {
@@ -2967,14 +2962,17 @@ public class FileUtils {
}
/**
- * Streams over the files in a given directory (and optionally
- * its subdirectories) which match an array of extensions.
+ * Streams over the files in a given directory (and optionally its subdirectories) which match an array of extensions.
+ * <p>
+ * The returned {@link Stream} may wrap one or more {@link DirectoryStream}s. When you require timely disposal of file system resources, use a
+ * {@code try}-with-resources block to ensure invocation of the stream's {@link Stream#close()} method after the stream operations are completed. Calling a
+ * closed stream causes a {@link IllegalStateException}.
+ * </p>
*
* @param directory the directory to search in
* @param recursive if true all subdirectories are searched as well
- * @param extensions an array of extensions, ex. {"java","xml"}. If this
- * parameter is {@code null}, all files are returned.
- * @return an iterator of java.io.File with the matching files
+ * @param extensions an array of extensions, for example, {"java","xml"}. If this parameter is {@code null}, all files are returned.
+ * @return a Stream of {@link File} for matching files.
* @throws IOException if an I/O error is thrown when accessing the starting file.
* @since 2.9.0
*/
@@ -3006,8 +3004,8 @@ public class FileUtils {
if (url == null || !"file".equalsIgnoreCase(url.getProtocol())) {
return null;
}
- final String filename = url.getFile().replace('/', File.separatorChar);
- return new File(decodeUrl(filename));
+ final String fileName = url.getFile().replace('/', File.separatorChar);
+ return new File(decodeUrl(fileName));
}
/**
@@ -3048,6 +3046,15 @@ public class FileUtils {
return files;
}
+ /**
+ * Consumes all of the given stream.
+ * <p>
+ * When called from a FileTreeWalker, the walker <em>closes</em> the stream because {@link FileTreeWalker#next()} calls {@code top.stream().close()}.
+ * </p>
+ *
+ * @param stream The stream to consume.
+ * @return a new List.
+ */
private static List<File> toList(final Stream<File> stream) {
return stream.collect(Collectors.toList());
}