You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2020/12/06 19:09:53 UTC
[commons-io] 03/03: Reimplement some FileUtils internals in terms
of refactored PathUtils methods to provide better behavioral compatibility
with older versions like 2.6 in the area of deleting read-only file system
elements.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git
commit 2bc7e31f1dee0cb6ff4f3c57a63ac09cd4c2d1aa
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Dec 6 14:09:44 2020 -0500
Reimplement some FileUtils internals in terms of refactored PathUtils
methods to provide better behavioral compatibility with older versions
like 2.6 in the area of deleting read-only file system elements.
Also clean up some Javadocs.
---
src/main/java/org/apache/commons/io/FileUtils.java | 211 ++++++++++-----------
.../commons/io/file/CleaningPathVisitor.java | 2 +-
.../commons/io/file/DeletingPathVisitor.java | 18 +-
.../java/org/apache/commons/io/file/PathUtils.java | 118 +++++++++---
4 files changed, 215 insertions(+), 134 deletions(-)
diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java
index 153666d..99b3386 100644
--- a/src/main/java/org/apache/commons/io/FileUtils.java
+++ b/src/main/java/org/apache/commons/io/FileUtils.java
@@ -238,55 +238,6 @@ public class FileUtils {
}
/**
- * Checks that the given {@code File} exists and is a directory.
- *
- * @param directory The {@code File} to check.
- * @return the given directory.
- * @throws IllegalArgumentException if the given {@code File} does not exist or is not a directory.
- */
- private static File checkDirectory(final File directory) {
- if (!directory.exists()) {
- throw new IllegalArgumentException(directory + " does not exist");
- }
- if (!directory.isDirectory()) {
- throw new IllegalArgumentException(directory + " is not a directory");
- }
- return directory;
- }
-
- /**
- * Checks that two file lengths are equal.
- *
- * @param srcFile Source file.
- * @param destFile Destination file.
- * @param srcLen Source file length.
- * @param dstLen Destination file length
- * @throws IOException Thrown when the given sizes are not equal.
- */
- private static void checkEqualSizes(final File srcFile, final File destFile, final long srcLen, final long dstLen)
- throws IOException {
- if (srcLen != dstLen) {
- throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile
- + "' Expected length: " + srcLen + " Actual: " + dstLen);
- }
- }
-
- /**
- * Checks requirements for file copy.
- *
- * @param source the source file
- * @param destination the destination
- * @throws FileNotFoundException if the destination does not exist
- */
- private static void checkFileRequirements(final File source, final File destination) throws FileNotFoundException {
- Objects.requireNonNull(source, "source");
- Objects.requireNonNull(destination, "target");
- if (!source.exists()) {
- throw new FileNotFoundException("Source '" + source + "' does not exist");
- }
- }
-
- /**
* Computes the checksum of a file using the specified checksum object.
* Multiple files may be checked using one <code>Checksum</code> instance
* if desired simply by reusing the same checksum object.
@@ -304,9 +255,7 @@ public class FileUtils {
* @since 1.3
*/
public static Checksum checksum(final File file, final Checksum checksum) throws IOException {
- if (file.isDirectory()) {
- throw new IllegalArgumentException("Checksums can't be computed on directories");
- }
+ requireFile(file, "file");
try (InputStream in = new CheckedInputStream(new FileInputStream(file), checksum)) {
IOUtils.consume(in);
}
@@ -717,7 +666,7 @@ public class FileUtils {
*/
public static void copyDirectory(final File srcDir, final File destDir, final FileFilter filter,
final boolean preserveFileDate, final CopyOption... copyOptions) throws IOException {
- checkFileRequirements(srcDir, destDir);
+ requireFileRequirements(srcDir, destDir);
if (!srcDir.isDirectory()) {
throw new IOException("Source '" + srcDir + "' exists but is not a directory");
}
@@ -875,7 +824,7 @@ public class FileUtils {
*/
public static void copyFile(final File srcFile, final File destFile, final boolean preserveFileDate, final CopyOption... copyOptions)
throws IOException {
- checkFileRequirements(srcFile, destFile);
+ requireFileRequirements(srcFile, destFile);
if (srcFile.isDirectory()) {
throw new IOException("Source '" + srcFile + "' exists but is a directory");
}
@@ -1041,7 +990,6 @@ public class FileUtils {
}
}
-
/**
* Copies a files to a directory preserving each file's date.
* <p>
@@ -1122,6 +1070,7 @@ public class FileUtils {
}
}
+
/**
* Copies bytes from the URL <code>source</code> to a file
* <code>destination</code>. The directories up to <code>destination</code>
@@ -1291,20 +1240,12 @@ public class FileUtils {
* @param child the file to consider as the child.
* @return true is the candidate leaf is under by the specified composite. False otherwise.
* @throws IOException if an IO error occurs while checking the files.
- * @throws IllegalArgumentException if {@code directory} is null or not a directory.
+ * @throws IllegalArgumentException if {@code directory} is not a directory.
* @see FilenameUtils#directoryContains(String, String)
* @since 2.2
*/
public static boolean directoryContains(final File directory, final File child) throws IOException {
-
- // Fail fast against NullPointerException
- if (directory == null) {
- throw new IllegalArgumentException("Directory must not be null");
- }
-
- if (!directory.isDirectory()) {
- throw new IllegalArgumentException("Not a directory: " + directory);
- }
+ requireDirectory(directory, "directory");
if (child == null) {
return false;
@@ -1399,9 +1340,9 @@ public class FileUtils {
Files.copy(srcPath, destPath, copyOptions);
// TODO IO-386: Do we still need this check?
- checkEqualSizes(srcFile, destFile, Files.size(srcPath), Files.size(destPath));
+ requireEqualSizes(srcFile, destFile, Files.size(srcPath), Files.size(destPath));
// TODO IO-386: Do we still need this check?
- checkEqualSizes(srcFile, destFile, srcFile.length(), destFile.length());
+ requireEqualSizes(srcFile, destFile, srcFile.length(), destFile.length());
if (preserveFileDate) {
setLastModified(srcFile, destFile);
@@ -1426,7 +1367,8 @@ public class FileUtils {
public static void forceDelete(final File file) throws IOException {
final Counters.PathCounters deleteCounters;
try {
- deleteCounters = PathUtils.delete(file.toPath(), StandardDeleteOption.OVERRIDE_READ_ONLY);
+ deleteCounters = PathUtils.delete(file.toPath(), PathUtils.EMPTY_LINK_OPTION_ARRAY,
+ StandardDeleteOption.OVERRIDE_READ_ONLY);
} catch (final IOException e) {
throw new IOException("Unable to delete file: " + file, e);
}
@@ -1713,11 +1655,7 @@ public class FileUtils {
* @throws IllegalArgumentException if the reference file doesn't exist
*/
public static boolean isFileNewer(final File file, final File reference) {
- Objects.requireNonNull(reference, "reference");
- if (!reference.exists()) {
- throw new IllegalArgumentException("The reference file '"
- + reference + "' doesn't exist");
- }
+ requireExists(reference, "reference");
return isFileNewer(file, reference.lastModified());
}
@@ -1882,10 +1820,7 @@ public class FileUtils {
* @throws IllegalArgumentException if the reference file doesn't exist
*/
public static boolean isFileOlder(final File file, final File reference) {
- if (!Objects.requireNonNull(reference, "reference").exists()) {
- throw new IllegalArgumentException("The reference file '"
- + reference + "' doesn't exist");
- }
+ requireExists(reference, "reference");
return isFileOlder(file, reference.lastModified());
}
@@ -1956,7 +1891,6 @@ public class FileUtils {
* The resulting iterator MUST be consumed in its entirety in order to close its underlying stream.
* </p>
* <p>
- * <p>
* All files found are filtered by an IOFileFilter.
* </p>
*
@@ -2152,6 +2086,7 @@ public class FileUtils {
throw new IllegalArgumentException(e);
}
}
+
/**
* Finds files within a given directory (and optionally its
* subdirectories). All files found are filtered by an IOFileFilter.
@@ -2249,7 +2184,6 @@ public class FileUtils {
}
moveDirectory(src, new File(destDir, src.getName()));
}
-
/**
* Moves a file.
* <p>
@@ -2478,7 +2412,6 @@ public class FileUtils {
return readFileToString(file, Charset.defaultCharset());
}
-
/**
* Reads the contents of a file into a String.
* The file is always closed.
@@ -2525,6 +2458,7 @@ public class FileUtils {
return readLines(file, Charset.defaultCharset());
}
+
/**
* Reads the contents of a file line by line to a List of Strings.
* The file is always closed.
@@ -2557,6 +2491,86 @@ public class FileUtils {
}
/**
+ * Requires that the given {@code File} exists and is a directory.
+ *
+ * @param directory The {@code File} to check.
+ * @param param The param name to use in the exception message in case of null input.
+ * @return the given directory.
+ * @throws IllegalArgumentException if the given {@code File} does not exist or is not a directory.
+ */
+ private static File requireDirectory(final File directory, String param) {
+ requireExists(directory, param);
+ if (!directory.isDirectory()) {
+ throw new IllegalArgumentException(directory + " is not a directory");
+ }
+ return directory;
+ }
+
+ /**
+ * Requires that two file lengths are equal.
+ *
+ * @param srcFile Source file.
+ * @param destFile Destination file.
+ * @param srcLen Source file length.
+ * @param dstLen Destination file length
+ * @throws IOException Thrown when the given sizes are not equal.
+ */
+ private static void requireEqualSizes(final File srcFile, final File destFile, final long srcLen, final long dstLen)
+ throws IOException {
+ if (srcLen != dstLen) {
+ throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile
+ + "' Expected length: " + srcLen + " Actual: " + dstLen);
+ }
+ }
+
+ /**
+ * Requires that the given {@code File} exists.
+ *
+ * @param file The {@code File} to check.
+ * @param param The param name to use in the exception message in case of null input.
+ * @return the given file.
+ * @throws IllegalArgumentException if the given {@code File} does not exist or is not a directory.
+ */
+ private static File requireExists(final File file, String param) {
+ Objects.requireNonNull(file, param);
+ if (!file.exists()) {
+ throw new IllegalArgumentException(file + " does not exist");
+ }
+ return file;
+ }
+
+ /**
+ * Requires that the given {@code File} exists and is a file.
+ *
+ * @param file The {@code File} to check.
+ * @param param The param name to use in the exception message in case of null input.
+ * @return the given file.
+ * @throws IllegalArgumentException if the given {@code File} does not exist or is not a directory.
+ */
+ private static File requireFile(final File file, String param) {
+ requireExists(file, param);
+ if (!file.isFile()) {
+ throw new IllegalArgumentException(file + " is not a file");
+ }
+ return file;
+ }
+
+ /**
+ * Requires requirements for file copy.
+ *
+ * @param source the source file
+ * @param destination the destination
+ * @throws FileNotFoundException if the destination does not exist
+ */
+ private static void requireFileRequirements(final File source, final File destination) throws FileNotFoundException {
+ Objects.requireNonNull(source, "source");
+ Objects.requireNonNull(destination, "target");
+ if (!source.exists()) {
+ throw new FileNotFoundException("Source '" + source + "' does not exist");
+ }
+ }
+
+ /**
* Sets the given {@code targetFile}'s last modified date to the value from {@code sourceFile}.
*
* @param sourceFile The source file to query.
@@ -2587,16 +2601,13 @@ public class FileUtils {
* @return the length of the file, or recursive size of the directory,
* provided (in bytes).
*
- * @throws NullPointerException if the file is {@code null}
+ * @throws NullPointerException if the file is {@code null}.
* @throws IllegalArgumentException if the file does not exist.
*
* @since 2.0
*/
public static long sizeOf(final File file) {
- if (!file.exists()) {
- final String message = file + " does not exist";
- throw new IllegalArgumentException(message);
- }
+ requireExists(file, "file");
if (file.isDirectory()) {
return sizeOfDirectory0(file); // private method; expects directory
}
@@ -2628,16 +2639,13 @@ public class FileUtils {
* @return the length of the file, or recursive size of the directory,
* provided (in bytes).
*
- * @throws NullPointerException if the file is {@code null}
+ * @throws NullPointerException if the file is {@code null}.
* @throws IllegalArgumentException if the file does not exist.
*
* @since 2.4
*/
public static BigInteger sizeOfAsBigInteger(final File file) {
- if (!file.exists()) {
- final String message = file + " does not exist";
- throw new IllegalArgumentException(message);
- }
+ requireExists(file, "file");
if (file.isDirectory()) {
return sizeOfDirectoryBig0(file); // internal method
}
@@ -2664,13 +2672,13 @@ public class FileUtils {
* method that does not overflow.
* </p>
*
- * @param directory directory to inspect, must not be {@code null}
+ * @param directory directory to inspect, must not be {@code null}.
* @return size of directory in bytes, 0 if directory is security restricted, a negative number when the real total
* is greater than {@link Long#MAX_VALUE}.
- * @throws NullPointerException if the directory is {@code null}
+ * @throws NullPointerException if the directory is {@code null}.
*/
public static long sizeOfDirectory(final File directory) {
- return sizeOfDirectory0(checkDirectory(directory));
+ return sizeOfDirectory0(requireDirectory(directory, "directory"));
}
/**
@@ -2700,13 +2708,13 @@ public class FileUtils {
/**
* Counts the size of a directory recursively (sum of the length of all files).
*
- * @param directory directory to inspect, must not be {@code null}
+ * @param directory directory to inspect, must not be {@code null}.
* @return size of directory in bytes, 0 if directory is security restricted.
- * @throws NullPointerException if the directory is {@code null}
+ * @throws NullPointerException if the directory is {@code null}.
* @since 2.4
*/
public static BigInteger sizeOfDirectoryAsBigInteger(final File directory) {
- return sizeOfDirectoryBig0(checkDirectory(directory));
+ return sizeOfDirectoryBig0(requireDirectory(directory, "directory"));
}
/**
@@ -2919,16 +2927,7 @@ public class FileUtils {
* @throws IOException if an I/O error occurs
*/
private static File[] verifiedListFiles(final File directory) throws IOException {
- if (!directory.exists()) {
- final String message = directory + " does not exist";
- throw new IllegalArgumentException(message);
- }
-
- if (!directory.isDirectory()) {
- final String message = directory + " is not a directory";
- throw new IllegalArgumentException(message);
- }
-
+ requireDirectory(directory, "directory");
final File[] files = directory.listFiles();
if (files == null) { // null if security restricted
throw new IOException("Failed to list contents of " + directory);
diff --git a/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java b/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java
index 9df929b..162ab8f 100644
--- a/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java
@@ -60,7 +60,7 @@ public class CleaningPathVisitor extends CountingPathVisitor {
* Constructs a new visitor that deletes files except for the files and directories explicitly given.
*
* @param pathCounter How to count visits.
- * @param deleteOption options indicating how deletion is handled.
+ * @param deleteOption How deletion is handled.
* @param skip The files to skip deleting.
* @since 2.8.0
*/
diff --git a/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java b/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java
index 6235b56..b6c85c5 100644
--- a/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java
@@ -61,18 +61,32 @@ public class DeletingPathVisitor extends CountingPathVisitor {
* Constructs a new visitor that deletes files except for the files and directories explicitly given.
*
* @param pathCounter How to count visits.
- * @param deleteOption options indicating how deletion is handled.
+ * @param deleteOption How deletion is handled.
* @param skip The files to skip deleting.
* @since 2.8.0
*/
public DeletingPathVisitor(final PathCounters pathCounter, final DeleteOption[] deleteOption, final String... skip) {
+ this(pathCounter, PathUtils.NOFOLLOW_LINK_OPTION_ARRAY, deleteOption, skip);
+ }
+
+ /**
+ * Constructs a new visitor that deletes files except for the files and directories explicitly given.
+ *
+ * @param pathCounter How to count visits.
+ * @param linkOptions How symbolic links are handled.
+ * @param deleteOption How deletion is handled.
+ * @param skip The files to skip deleting.
+ * @since 2.9.0
+ */
+ public DeletingPathVisitor(final PathCounters pathCounter, final LinkOption[] linkOptions,
+ final DeleteOption[] deleteOption, final String... skip) {
super(pathCounter);
final String[] temp = skip != null ? skip.clone() : EMPTY_STRING_ARRAY;
Arrays.sort(temp);
this.skip = temp;
this.overrideReadOnly = StandardDeleteOption.overrideReadOnly(deleteOption);
// TODO Files.deleteIfExists() never follows links, so use LinkOption.NOFOLLOW_LINKS in other calls to Files.
- this.linkOptions = PathUtils.NOFOLLOW_LINK_OPTION_ARRAY.clone();
+ this.linkOptions = linkOptions == null ? PathUtils.NOFOLLOW_LINK_OPTION_ARRAY : linkOptions.clone();
}
/**
diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java b/src/main/java/org/apache/commons/io/file/PathUtils.java
index 0ce9e6c..2ccd609 100644
--- a/src/main/java/org/apache/commons/io/file/PathUtils.java
+++ b/src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -152,6 +152,13 @@ public final class PathUtils {
public static final LinkOption[] EMPTY_LINK_OPTION_ARRAY = new LinkOption[0];
/**
+ * {@link LinkOption} array for {@link LinkOption#NOFOLLOW_LINKS}.
+ *
+ * @since 2.9.0
+ */
+ public static final LinkOption[] NOFOLLOW_LINK_OPTION_ARRAY = new LinkOption[] {LinkOption.NOFOLLOW_LINKS};
+
+ /**
* Empty {@link OpenOption} array.
*/
public static final OpenOption[] EMPTY_OPEN_OPTION_ARRAY = new OpenOption[0];
@@ -193,13 +200,14 @@ public final class PathUtils {
* Cleans a directory including sub-directories without deleting directories.
*
* @param directory directory to clean.
- * @param options options indicating how deletion is handled.
+ * @param deleteOptions How deletion is handled.
* @return The visitation path counters.
* @throws IOException if an I/O error is thrown by a visitor method.
* @since 2.8.0
*/
- public static PathCounters cleanDirectory(final Path directory, final DeleteOption... options) throws IOException {
- return visitFileTree(new CleaningPathVisitor(Counters.longPathCounters(), options), directory)
+ public static PathCounters cleanDirectory(final Path directory, final DeleteOption... deleteOptions)
+ throws IOException {
+ return visitFileTree(new CleaningPathVisitor(Counters.longPathCounters(), deleteOptions), directory)
.getPathCounters();
}
@@ -347,16 +355,42 @@ public final class PathUtils {
* </ul>
*
* @param path file or directory to delete, must not be {@code null}
- * @param options options indicating how deletion is handled.
+ * @param deleteOptions How deletion is handled.
* @return The visitor used to delete the given directory.
* @throws NullPointerException if the directory is {@code null}
* @throws IOException if an I/O error is thrown by a visitor method or if an I/O error occurs.
* @since 2.8.0
*/
- public static PathCounters delete(final Path path, final DeleteOption... options) throws IOException {
+ public static PathCounters delete(final Path path, final DeleteOption... deleteOptions) throws IOException {
+ // File deletion through Files deletes links, not targets, so use LinkOption.NOFOLLOW_LINKS.
+ return Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS) ? deleteDirectory(path, deleteOptions)
+ : deleteFile(path, deleteOptions);
+ }
+
+ /**
+ * Deletes a file or directory. If the path is a directory, delete it and all sub-directories.
+ * <p>
+ * The difference between File.delete() and this method are:
+ * </p>
+ * <ul>
+ * <li>A directory to delete does not have to be empty.</li>
+ * <li>You get exceptions when a file or directory cannot be deleted; {@link java.io.File#delete()} returns a
+ * boolean.
+ * </ul>
+ *
+ * @param path file or directory to delete, must not be {@code null}
+ * @param linkOptions configures how symbolic links are handled.
+ * @param deleteOptions How deletion is handled.
+ * @return The visitor used to delete the given directory.
+ * @throws NullPointerException if the directory is {@code null}
+ * @throws IOException if an I/O error is thrown by a visitor method or if an I/O error occurs.
+ * @since 2.9.0
+ */
+ public static PathCounters delete(final Path path, final LinkOption[] linkOptions,
+ final DeleteOption... deleteOptions) throws IOException {
// File deletion through Files deletes links, not targets, so use LinkOption.NOFOLLOW_LINKS.
- return Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS) ? deleteDirectory(path, options)
- : deleteFile(path, options);
+ return Files.isDirectory(path, linkOptions) ? deleteDirectory(path, linkOptions, deleteOptions)
+ : deleteFile(path, linkOptions, deleteOptions);
}
/**
@@ -374,14 +408,32 @@ public final class PathUtils {
* Deletes a directory including sub-directories.
*
* @param directory directory to delete.
- * @param options options indicating how deletion is handled.
+ * @param deleteOptions How deletion is handled.
* @return The visitor used to delete the given directory.
* @throws IOException if an I/O error is thrown by a visitor method.
* @since 2.8.0
*/
- public static PathCounters deleteDirectory(final Path directory, final DeleteOption... options) throws IOException {
- return visitFileTree(new DeletingPathVisitor(Counters.longPathCounters(), options), directory)
- .getPathCounters();
+ public static PathCounters deleteDirectory(final Path directory, final DeleteOption... deleteOptions)
+ throws IOException {
+ return visitFileTree(
+ new DeletingPathVisitor(Counters.longPathCounters(), PathUtils.NOFOLLOW_LINK_OPTION_ARRAY, deleteOptions),
+ directory).getPathCounters();
+ }
+
+ /**
+ * Deletes a directory including sub-directories.
+ *
+ * @param directory directory to delete.
+ * @param linkOptions configures how symbolic links are handled.
+ * @param deleteOptions How deletion is handled.
+ * @return The visitor used to delete the given directory.
+ * @throws IOException if an I/O error is thrown by a visitor method.
+ * @since 2.9.0
+ */
+ public static PathCounters deleteDirectory(final Path directory, final LinkOption[] linkOptions,
+ final DeleteOption... deleteOptions) throws IOException {
+ return visitFileTree(new DeletingPathVisitor(Counters.longPathCounters(), linkOptions, deleteOptions),
+ directory).getPathCounters();
}
/**
@@ -400,22 +452,38 @@ public final class PathUtils {
* Deletes the given file.
*
* @param file The file to delete.
- * @param options options indicating how deletion is handled.
+ * @param deleteOptions How deletion is handled.
* @return A visitor with path counts set to 1 file, 0 directories, and the size of the deleted file.
* @throws IOException if an I/O error occurs.
* @throws NoSuchFileException if the file is a directory.
* @since 2.8.0
*/
- public static PathCounters deleteFile(final Path file, final DeleteOption... options) throws IOException {
+ public static PathCounters deleteFile(final Path file, final DeleteOption... deleteOptions) throws IOException {
// Files.deleteIfExists() never follows links, so use LinkOption.NOFOLLOW_LINKS in other calls to Files.
- if (Files.isDirectory(file, LinkOption.NOFOLLOW_LINKS)) {
+ return deleteFile(file, NOFOLLOW_LINK_OPTION_ARRAY, deleteOptions);
+ }
+
+ /**
+ * Deletes the given file.
+ *
+ * @param file The file to delete.
+ * @param linkOptions configures how symbolic links are handled.
+ * @param deleteOptions How deletion is handled.
+ * @return A visitor with path counts set to 1 file, 0 directories, and the size of the deleted file.
+ * @throws IOException if an I/O error occurs.
+ * @throws NoSuchFileException if the file is a directory.
+ * @since 2.9.0
+ */
+ public static PathCounters deleteFile(final Path file, final LinkOption[] linkOptions,
+ final DeleteOption... deleteOptions) throws NoSuchFileException, IOException {
+ if (Files.isDirectory(file, linkOptions)) {
throw new NoSuchFileException(file.toString());
}
final PathCounters pathCounts = Counters.longPathCounters();
- final boolean exists = Files.exists(file, LinkOption.NOFOLLOW_LINKS);
+ final boolean exists = Files.exists(file, linkOptions);
final long size = exists ? Files.size(file) : 0;
- if (overrideReadOnly(options) && exists) {
- setReadOnly(file, false, LinkOption.NOFOLLOW_LINKS);
+ if (overrideReadOnly(deleteOptions) && exists) {
+ setReadOnly(file, false, linkOptions);
}
if (Files.deleteIfExists(file)) {
pathCounts.getFileCounter().increment();
@@ -727,14 +795,14 @@ public final class PathUtils {
/**
* Returns true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}.
*
- * @param options the array to test
+ * @param deleteOptions the array to test
* @return true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}.
*/
- private static boolean overrideReadOnly(final DeleteOption[] options) {
- if (options == null) {
+ private static boolean overrideReadOnly(final DeleteOption... deleteOptions) {
+ if (deleteOptions == null) {
return false;
}
- for (final DeleteOption deleteOption : options) {
+ for (final DeleteOption deleteOption : deleteOptions) {
if (deleteOption == StandardDeleteOption.OVERRIDE_READ_ONLY) {
return true;
}
@@ -797,21 +865,21 @@ public final class PathUtils {
*
* @param path The path to set.
* @param readOnly true for read-only, false for not read-only.
- * @param options options indicating how symbolic links are handled.
+ * @param linkOptions options indicating how symbolic links are handled.
* @return The given path.
* @throws IOException if an I/O error occurs.
* @since 2.8.0
*/
- public static Path setReadOnly(final Path path, final boolean readOnly, final LinkOption... options)
+ public static Path setReadOnly(final Path path, final boolean readOnly, final LinkOption... linkOptions)
throws IOException {
final DosFileAttributeView fileAttributeView = Files.getFileAttributeView(path, DosFileAttributeView.class,
- options);
+ linkOptions);
if (fileAttributeView != null) {
fileAttributeView.setReadOnly(readOnly);
return path;
}
final PosixFileAttributeView posixFileAttributeView = Files.getFileAttributeView(path,
- PosixFileAttributeView.class, options);
+ PosixFileAttributeView.class, linkOptions);
if (posixFileAttributeView != null) {
// Works on Windows but not on Ubuntu:
// Files.setAttribute(path, "unix:readonly", readOnly, options);