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
The following commit(s) were added to refs/heads/master by this push: new d75027d Add and use PathUtils.isOlder(Path, FileTime, LinkOption...) d75027d is described below commit d75027d357838e4a56ff43a233169942b12ef7a1 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Tue Sep 14 18:49:41 2021 -0400 Add and use PathUtils.isOlder(Path, FileTime, LinkOption...) - Add and use PathUtils.isOlder(Path, Instant, LinkOption...) - Add and use PathUtils.isOlder(Path, long, LinkOption...) - Add and use PathUtils.isOlder(Path, Path) - Add FileUtils.byteCountToDisplaySize(Number) --- src/changes/changes.xml | 6 ++ src/main/java/org/apache/commons/io/FileUtils.java | 95 +++++++++++++++++----- .../java/org/apache/commons/io/file/PathUtils.java | 77 ++++++++++++++++-- .../org/apache/commons/io/FileUtilsTestCase.java | 25 ++++++ 4 files changed, 177 insertions(+), 26 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 4d34fdf..4670cb0 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -184,6 +184,12 @@ The <action> type attribute can be add,update,fix,remove. Add and use PathUtils.isNewer(Path, Path) for more precision. Add and use FileUtils.isNewer(File, FileTime) for more precision. </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add and use PathUtils.isOlder(Path, FileTime, LinkOption...) + Add and use PathUtils.isOlder(Path, Instant, LinkOption...) + Add and use PathUtils.isOlder(Path, long, LinkOption...) + Add and use PathUtils.isOlder(Path, Path) + </action> <!-- UPDATE --> <action dev="ggregory" type="add" due-to="Gary Gregory"> Update FileEntry to use FileTime instead of long for file time stamps. diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index a14ea28..d729f86 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -267,6 +267,26 @@ public class FileUtils { } /** + * Returns a human-readable version of the file size, where the input represents a specific number of bytes. + * <p> + * If the size is over 1GB, the size is returned as the number of whole GB, i.e. the size is rounded down to the + * nearest GB boundary. + * </p> + * <p> + * Similarly for the 1MB and 1KB boundaries. + * </p> + * + * @param size the number of bytes + * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes) + * @see <a href="https://issues.apache.org/jira/browse/IO-226">IO-226 - should the rounding be changed?</a> + * @since 2.12.0 + */ + // See https://issues.apache.org/jira/browse/IO-226 - should the rounding be changed? + public static String byteCountToDisplaySize(final Number size) { + return byteCountToDisplaySize(size.longValue()); + } + + /** * Computes the checksum of a file using the specified checksum object. Multiple files may be checked using one * {@code Checksum} instance if desired simply by reusing the same checksum object. For example: * @@ -1561,22 +1581,6 @@ public class FileUtils { } /** - * Tests if the specified {@code File} is newer than the specified {@code FileTime}. - * - * @param file the {@code File} of which the modification date must be compared. - * @param fileTime the file time reference. - * @return true if the {@code File} exists and has been modified after the given {@code FileTime}. - * @throws IOException if an I/O error occurs. - * @throws NullPointerException if the file or local date is {@code null}. - * - * @since 2.12.0 - */ - public static boolean isFileNewer(final File file, final FileTime fileTime) throws IOException { - Objects.requireNonNull(file, "file"); - return PathUtils.isNewer(file.toPath(), fileTime); - } - - /** * Tests if the specified {@code File} is newer than the specified {@code ChronoLocalDate} * at the specified time. * @@ -1696,6 +1700,22 @@ public class FileUtils { } /** + * Tests if the specified {@code File} is newer than the specified {@code FileTime}. + * + * @param file the {@code File} of which the modification date must be compared. + * @param fileTime the file time reference. + * @return true if the {@code File} exists and has been modified after the given {@code FileTime}. + * @throws IOException if an I/O error occurs. + * @throws NullPointerException if the file or local date is {@code null}. + * + * @since 2.12.0 + */ + public static boolean isFileNewer(final File file, final FileTime fileTime) throws IOException { + Objects.requireNonNull(file, "file"); + return PathUtils.isNewer(file.toPath(), fileTime); + } + + /** * Tests if the specified {@code File} is newer than the specified {@code Instant}. * * @param file the {@code File} of which the modification date must be compared. @@ -1864,7 +1884,28 @@ public class FileUtils { */ public static boolean isFileOlder(final File file, final File reference) { requireExists(reference, "reference"); - return isFileOlder(file, lastModifiedUnchecked(reference)); + try { + return PathUtils.isOlder(file.toPath(), reference.toPath()); + } catch (final IOException e) { + // TODO Update method signature + throw new UncheckedIOException(e); + } + } + + /** + * Tests if the specified {@code File} is older than the specified {@code FileTime}. + * + * @param file the {@code File} of which the modification date must be compared. + * @param fileTime the file time reference. + * @return true if the {@code File} exists and has been modified before the given {@code FileTime}. + * @throws IOException if an I/O error occurs. + * @throws NullPointerException if the file or local date is {@code null}. + * + * @since 2.12.0 + */ + public static boolean isFileOlder(final File file, final FileTime fileTime) throws IOException { + Objects.requireNonNull(file, "file"); + return PathUtils.isOlder(file.toPath(), fileTime); } /** @@ -1878,7 +1919,12 @@ public class FileUtils { */ public static boolean isFileOlder(final File file, final Instant instant) { Objects.requireNonNull(instant, "instant"); - return isFileOlder(file, instant.toEpochMilli()); + try { + return PathUtils.isOlder(file.toPath(), instant); + } catch (final IOException e) { + // TODO Update method signature + throw new UncheckedIOException(e); + } } /** @@ -1892,7 +1938,12 @@ public class FileUtils { */ public static boolean isFileOlder(final File file, final long timeMillis) { Objects.requireNonNull(file, "file"); - return file.exists() && lastModifiedUnchecked(file) < timeMillis; + try { + return PathUtils.isOlder(file.toPath(), timeMillis); + } catch (final IOException e) { + // TODO Update method signature + throw new UncheckedIOException(e); + } } /** @@ -2008,6 +2059,9 @@ public class FileUtils { * Returns the last modification time in milliseconds via * {@link java.nio.file.Files#getLastModifiedTime(Path, LinkOption...)}. * <p> + * For the best precision, use {@link #lastModifiedFileTime(File)}. + * </p> + * <p> * Use this method to avoid issues with {@link File#lastModified()} like * <a href="https://bugs.openjdk.java.net/browse/JDK-8177809">JDK-8177809</a> where {@link File#lastModified()} is * losing milliseconds (always ends in 000). This bug exists in OpenJDK 8 and 9, and is fixed in 10. @@ -2050,6 +2104,9 @@ public class FileUtils { * Returns the last modification time in milliseconds via * {@link java.nio.file.Files#getLastModifiedTime(Path, LinkOption...)}. * <p> + * For the best precision, use {@link #lastModifiedFileTime(File)}. + * </p> + * <p> * Use this method to avoid issues with {@link File#lastModified()} like * <a href="https://bugs.openjdk.java.net/browse/JDK-8177809">JDK-8177809</a> where {@link File#lastModified()} is * losing milliseconds (always ends in 000). This bug exists in OpenJDK 8 and 9, and is fixed in 10. 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 ab63893..b7e736c 100644 --- a/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -231,7 +231,7 @@ public final class PathUtils { * @throws NullPointerException if the file is {@code null} */ private static int compareLastModifiedTimeTo(final Path file, final FileTime fileTime, final LinkOption... options) throws IOException { - return Files.getLastModifiedTime(file, options).compareTo(fileTime); + return getLastModifiedTime(file, options).compareTo(fileTime); } /** @@ -712,6 +712,10 @@ public final class PathUtils { return fileAttributeView == null ? null : fileAttributeView.getAcl(); } + private static FileTime getLastModifiedTime(final Path path, final LinkOption... options) throws IOException { + return Files.getLastModifiedTime(Objects.requireNonNull(path, "path"), options); + } + /** * Returns a {@link Path} representing the system temporary directory. * @@ -819,8 +823,7 @@ public final class PathUtils { * * @param file the {@code Path} of which the modification date must be compared * @param instant the time reference. - * @param options options indicating how symbolic links are handled * @return true if the {@code Path} exists and has - * been modified after the given time reference. + * @param options options indicating how symbolic links are handled. * @return true if the {@code Path} exists and has been modified after the given time reference. * @throws IOException if an I/O error occurs. * @throws NullPointerException if the file is {@code null} @@ -835,8 +838,7 @@ public final class PathUtils { * * @param file the {@code Path} of which the modification date must be compared * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970) - * @param options options indicating how symbolic links are handled * @return true if the {@code Path} exists and has - * been modified after the given time reference. + * @param options options indicating how symbolic links are handled. * @return true if the {@code Path} exists and has been modified after the given time reference. * @throws IOException if an I/O error occurs. * @throws NullPointerException if the file is {@code null} @@ -857,7 +859,68 @@ public final class PathUtils { * @since 2.12.0 */ public static boolean isNewer(final Path file, final Path reference) throws IOException { - return isNewer(file, Files.getLastModifiedTime(reference)); + return isNewer(file, getLastModifiedTime(reference)); + } + + /** + * Tests if the specified {@code Path} is older than the specified time reference. + * + * @param file the {@code Path} of which the modification date must be compared. + * @param fileTime the time reference. + * @param options options indicating how symbolic links are handled been modified after the given time reference. + * @return true if the {@code Path} exists and has been modified before the given time reference. + * @throws IOException if an I/O error occurs. + * @throws NullPointerException if the file is {@code null} + * @since 2.12.0 + */ + public static boolean isOlder(final Path file, final FileTime fileTime, final LinkOption... options) throws IOException { + if (notExists(file)) { + return false; + } + return compareLastModifiedTimeTo(file, fileTime, options) < 0; + } + + /** + * Tests if the specified {@code Path} is older than the specified time reference. + * + * @param file the {@code Path} of which the modification date must be compared. + * @param instant the time reference. + * @param options options indicating how symbolic links are handled. + * @return true if the {@code Path} exists and has been modified after the given time reference. + * @throws IOException if an I/O error occurs. + * @throws NullPointerException if the file is {@code null} + * @since 2.12.0 + */ + public static boolean isOlder(final Path file, final Instant instant, final LinkOption... options) throws IOException { + return isOlder(file, FileTime.from(instant), options); + } + + /** + * Tests if the specified {@code Path} is older than the specified time reference. + * + * @param file the {@code Path} of which the modification date must be compared + * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970) + * @param options options indicating how symbolic links are handled been modified after the given time reference. + * @return true if the {@code Path} exists and has been modified before the given time reference. + * @throws IOException if an I/O error occurs. + * @throws NullPointerException if the file is {@code null} + * @since 2.12.0 + */ + public static boolean isOlder(final Path file, final long timeMillis, final LinkOption... options) throws IOException { + return isOlder(file, FileTime.fromMillis(timeMillis), options); + } + + /** + * Tests if the specified {@code Path} is older than the reference {@code Path}. + * + * @param file the {@code File} of which the modification date must be compared. + * @param reference the {@code File} of which the modification date is used. + * @return true if the {@code File} exists and has been modified before than the reference {@code File}. + * @throws IOException if an I/O error occurs. + * @since 2.12.0 + */ + public static boolean isOlder(final Path file, final Path reference) throws IOException { + return isOlder(file, getLastModifiedTime(reference)); } /** @@ -1009,7 +1072,7 @@ public final class PathUtils { */ public static void setLastModifiedTime(final Path sourceFile, final Path targetFile) throws IOException { Objects.requireNonNull(sourceFile, "sourceFile"); - Files.setLastModifiedTime(targetFile, Files.getLastModifiedTime(sourceFile)); + Files.setLastModifiedTime(targetFile, getLastModifiedTime(sourceFile)); } /** diff --git a/src/test/java/org/apache/commons/io/FileUtilsTestCase.java b/src/test/java/org/apache/commons/io/FileUtilsTestCase.java index b096639..870497f 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsTestCase.java +++ b/src/test/java/org/apache/commons/io/FileUtilsTestCase.java @@ -459,6 +459,31 @@ public class FileUtilsTestCase { } @Test + public void testByteCountToDisplaySizeNumber() { + assertEquals("0 bytes", FileUtils.byteCountToDisplaySize(Integer.valueOf(0))); + assertEquals("1 bytes", FileUtils.byteCountToDisplaySize(Integer.valueOf(1))); + assertEquals("1023 bytes", FileUtils.byteCountToDisplaySize(Integer.valueOf(1023))); + assertEquals("1 KB", FileUtils.byteCountToDisplaySize(Integer.valueOf(1024))); + assertEquals("1 KB", FileUtils.byteCountToDisplaySize(Integer.valueOf(1025))); + assertEquals("1023 KB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1023))); + assertEquals("1 MB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024))); + assertEquals("1 MB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1025))); + assertEquals("1023 MB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1023))); + assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1024))); + assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1025))); + assertEquals("2 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 2))); + assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1024 * 2 - 1))); + assertEquals("1 TB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 1024))); + assertEquals("1 PB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 1024 * 1024))); + assertEquals("1 EB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 1024 * 1024 * 1024))); + assertEquals("7 EB", FileUtils.byteCountToDisplaySize(Long.valueOf(Long.MAX_VALUE))); + // Other MAX_VALUEs + assertEquals("63 KB", FileUtils.byteCountToDisplaySize(Integer.valueOf(Character.MAX_VALUE))); + assertEquals("31 KB", FileUtils.byteCountToDisplaySize(Short.valueOf(Short.MAX_VALUE))); + assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Integer.valueOf(Integer.MAX_VALUE))); + } + + @Test public void testChecksum() throws Exception { // create a test file final String text = "Imagination is more important than knowledge - Einstein";