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 2022/07/19 12:49:38 UTC
[commons-io] branch master updated: Add PathUtils.getLastModifiedFileTime(*).
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 cb6f3aab Add PathUtils.getLastModifiedFileTime(*).
cb6f3aab is described below
commit cb6f3aabcf872aeab3bb4c975d163f340b93f051
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Jul 19 08:49:31 2022 -0400
Add PathUtils.getLastModifiedFileTime(*).
---
src/changes/changes.xml | 3 +
.../java/org/apache/commons/io/file/PathUtils.java | 71 ++++++++++++++++++++++
.../org/apache/commons/io/file/PathUtilsTest.java | 51 ++++++++++++++--
3 files changed, 120 insertions(+), 5 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5fc2e954..83760b2f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -403,6 +403,9 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="add" due-to="Gary Gregory">
Add XmlStreamWriter(OutputStream, Charset).
</action>
+ <action dev="ggregory" type="add" due-to="Gary Gregory">
+ Add PathUtils.getLastModifiedFileTime(*).
+ </action>
<!-- UPDATE -->
<action dev="kinow" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/cache from 2.1.6 to 3.0.5 #307, #337.
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 32292bb4..85b1d5be 100644
--- a/src/main/java/org/apache/commons/io/file/PathUtils.java
+++ b/src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -24,6 +24,7 @@ import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.AccessDeniedException;
@@ -812,6 +813,76 @@ public final class PathUtils {
return Files.getFileAttributeView(path, DosFileAttributeView.class, options);
}
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ * <p>
+ * The method provides a workaround for bug <a href="https://bugs.openjdk.java.net/browse/JDK-8177809">JDK-8177809</a>
+ * where {@link File#lastModified()} looses milliseconds and always ends in 000. This bug is in OpenJDK 8 and 9, and
+ * fixed in 11.
+ * </p>
+ *
+ * @param file the file to query.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final File file) throws IOException {
+ return getLastModifiedFileTime(file.toPath(), null, EMPTY_LINK_OPTION_ARRAY);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param path the file to query.
+ * @param options options indicating how symbolic links are handled.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final Path path, final LinkOption... options) throws IOException {
+ return getLastModifiedFileTime(path, null, options);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param path the file to query.
+ * @param defaultIfAbsent Returns this file time of the file does not exist, may be null.
+ * @param options options indicating how symbolic links are handled.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final Path path, final FileTime defaultIfAbsent, final LinkOption... options) throws IOException {
+ return Files.exists(path) ? getLastModifiedTime(path, options) : defaultIfAbsent;
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param uri the file to query.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final URI uri) throws IOException {
+ return getLastModifiedFileTime(Paths.get(uri), null, EMPTY_LINK_OPTION_ARRAY);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param url the file to query.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @throws URISyntaxException if the URL is not formatted strictly according to to RFC2396 and cannot be converted to a
+ * URI.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final URL url) throws IOException, URISyntaxException {
+ return getLastModifiedFileTime(url.toURI());
+ }
+
private static FileTime getLastModifiedTime(final Path path, final LinkOption... options) throws IOException {
return Files.getLastModifiedTime(Objects.requireNonNull(path, "path"), options);
}
diff --git a/src/test/java/org/apache/commons/io/file/PathUtilsTest.java b/src/test/java/org/apache/commons/io/file/PathUtilsTest.java
index 503828fb..4f2100e1 100644
--- a/src/test/java/org/apache/commons/io/file/PathUtilsTest.java
+++ b/src/test/java/org/apache/commons/io/file/PathUtilsTest.java
@@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
@@ -31,6 +32,7 @@ import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
@@ -89,10 +91,18 @@ public class PathUtilsTest extends AbstractTempDirTest {
return symlinkDir;
}
+ private Path current() {
+ return PathUtils.current();
+ }
+
private Long getLastModifiedMillis(final Path file) throws IOException {
return Files.getLastModifiedTime(file).toMillis();
}
+ private Path getNonExistantPath() {
+ return Paths.get("/does not exist/for/certain");
+ }
+
private FileSystem openArchive(final Path p, final boolean createNew) throws IOException {
if (createNew) {
final Map<String, String> env = new HashMap<>();
@@ -227,6 +237,37 @@ public class PathUtilsTest extends AbstractTempDirTest {
assertThrowsExactly(FileAlreadyExistsException.class, () -> PathUtils.createParentDirectories(symlinkedDir.resolve("child")));
}
+ @Test
+ public void testGetLastModifiedFileTime_File_Present() throws IOException {
+ assertNotNull(PathUtils.getLastModifiedFileTime(current().toFile()));
+ }
+
+ @Test
+ public void testGetLastModifiedFileTime_Path_Absent() throws IOException {
+ assertNull(PathUtils.getLastModifiedFileTime(getNonExistantPath()));
+ }
+
+ @Test
+ public void testGetLastModifiedFileTime_Path_FileTime_Absent() throws IOException {
+ final FileTime fromMillis = FileTime.fromMillis(0);
+ assertEquals(fromMillis, PathUtils.getLastModifiedFileTime(getNonExistantPath(), fromMillis));
+ }
+
+ @Test
+ public void testGetLastModifiedFileTime_Path_Present() throws IOException {
+ assertNotNull(PathUtils.getLastModifiedFileTime(current()));
+ }
+
+ @Test
+ public void testGetLastModifiedFileTime_URI_Present() throws IOException {
+ assertNotNull(PathUtils.getLastModifiedFileTime(current().toUri()));
+ }
+
+ @Test
+ public void testGetLastModifiedFileTime_URL_Present() throws IOException, URISyntaxException {
+ assertNotNull(PathUtils.getLastModifiedFileTime(current().toUri().toURL()));
+ }
+
@Test
public void testGetTempDirectory() {
final Path tempDirectory = Paths.get(System.getProperty("java.io.tmpdir"));
@@ -254,12 +295,12 @@ public class PathUtilsTest extends AbstractTempDirTest {
public void testIsPosix() throws IOException {
boolean isPosix;
try {
- Files.getPosixFilePermissions(PathUtils.current());
+ Files.getPosixFilePermissions(current());
isPosix = true;
} catch (final UnsupportedOperationException e) {
isPosix = false;
}
- assertEquals(isPosix, PathUtils.isPosix(PathUtils.current()));
+ assertEquals(isPosix, PathUtils.isPosix(current()));
}
@Test
@@ -278,7 +319,7 @@ public class PathUtilsTest extends AbstractTempDirTest {
@Test
public void testNewDirectoryStream() throws Exception {
final PathFilter pathFilter = new NameFileFilter(PATH_FIXTURE);
- try (DirectoryStream<Path> stream = PathUtils.newDirectoryStream(PathUtils.current(), pathFilter)) {
+ try (DirectoryStream<Path> stream = PathUtils.newDirectoryStream(current(), pathFilter)) {
final Iterator<Path> iterator = stream.iterator();
final Path path = iterator.next();
assertEquals(PATH_FIXTURE, path.getFileName().toString());
@@ -336,12 +377,12 @@ public class PathUtilsTest extends AbstractTempDirTest {
public void testReadAttributesPosix() throws IOException {
boolean isPosix;
try {
- Files.getPosixFilePermissions(PathUtils.current());
+ Files.getPosixFilePermissions(current());
isPosix = true;
} catch (final UnsupportedOperationException e) {
isPosix = false;
}
- assertEquals(isPosix, PathUtils.readAttributes(PathUtils.current(), PosixFileAttributes.class) != null);
+ assertEquals(isPosix, PathUtils.readAttributes(current(), PosixFileAttributes.class) != null);
}
@Test