Add PathUtils.isPosix(Path, LinkOption...).
Add PathUtils.readAttributes(Path, Class<A>, LinkOption...).
MODIFY
src/main/java/org/apache/commons/io/file/PathUtils.java
src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -980,6 +980,41 @@ public static boolean isOlder(final Path file, final Path reference) throws IOEx
return isOlder(file, getLastModifiedTime(reference));
}
+ /**
+ * Tests whether the given path is on a POSIX file system.
+ *
+ * @param test The Path to test.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if test is on a POSIX file system.
+ * @since 2.12.0
+ */
+ public static boolean isPosix(final Path test, final LinkOption... options) {
+ return readAttributes(test, PosixFileAttributes.class, options) != null;
+ }
+
+ /**
+ * Calls {@link Files#readAttributes(Path, Class, LinkOption...)} but returns null instead of throwing
+ * {@link UnsupportedOperationException} or {@link IOException}.
+ *
+ * @param <A> The {@code BasicFileAttributes} type
+ * @param test The Path to test.
+ * @param type the {@code Class} of the file attributes required to read.
+ * @param options options indicating how to handle symbolic links.
+ * @return the file attributes.
+ * @since 2.12.0
+ */
+ public static <A extends BasicFileAttributes> A readAttributes(final Path test, final Class<A> type, final LinkOption... options) {
+ try {
+ return Files.readAttributes(test, type, options);
+ } catch (final UnsupportedOperationException e) {
+ // For example, on Windows.
+ return null;
+ } catch (final IOException e) {
+ // For example, when the path does not exist.
+ return null;
+ }
+ }
+
/**
* Tests whether the given {@code Path} is a regular file or not. Implemented as a null-safe delegate to
* {@code Files.isRegularFile(Path path, LinkOption... options)}.

MODIFY
src/test/java/org/apache/commons/io/file/PathUtilsTest.java
src/test/java/org/apache/commons/io/file/PathUtilsTest.java
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.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import java.nio.file.Paths;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashMap;
import java.util.Iterator;
@@ -186,6 +188,19 @@ public void testIsDirectory() throws IOException {
assertFalse(PathUtils.isDirectory(tempDir));
}
+ @Test
+ public void testIsPosix() throws IOException {
+ boolean isPosix;
+ try {
+ Files.getPosixFilePermissions(PathUtils.current());
+ isPosix = true;
+ } catch (UnsupportedOperationException e) {
+ isPosix = false;
+ }
+ assertEquals(isPosix, PathUtils.isPosix(PathUtils.current()));
+ assertEquals(false, PathUtils.isPosix(Paths.get("does not.exist")));
+ }
+
@Test
public void testIsRegularFile() throws IOException {
assertFalse(PathUtils.isRegularFile(null));
@@ -237,6 +252,19 @@ public void testNewOutputStreamNewFileAppendTrue() throws IOException {
testNewOutputStreamNewFile(true);
}
+ @Test
+ public void testReadAttributesPosix() throws IOException {
+ boolean isPosix;
+ try {
+ Files.getPosixFilePermissions(PathUtils.current());
+ isPosix = true;
+ } catch (UnsupportedOperationException e) {
+ isPosix = false;
+ }
+ assertEquals(isPosix, PathUtils.readAttributes(PathUtils.current(), PosixFileAttributes.class) != null);
+ assertNull(PathUtils.readAttributes(Paths.get("does not.exist"), PosixFileAttributes.class));
+ }
+
@Test
public void testReadStringEmptyFile() throws IOException {
final Path path = Paths.get("src/test/resources/org/apache/commons/io/test-file-empty.bin");

Add PathUtils.isPosix(Path, LinkOption...). (#290)

Add PathUtils.readAttributes(Path, Class<A>, LinkOption...).

Co-authored-by: Gary Gregory <ggregory@rocketsoftware.com>