使用 RandomAccessFile 读取文件属性

Read file attributes using RandomAccessFile

是否可以使用 RandomAccessFile 获取任何文件属性?

我所说的文件属性是指 class UnixFileAttributes:

中提供的 Unix 实现
class UnixFileAttributes
    implements PosixFileAttributes
{
    private int     st_mode;
    private long    st_ino;
    private long    st_dev;
    private long    st_rdev;
    private int     st_nlink;
    private int     st_uid;
    private int     st_gid;
    private long    st_size;
    private long    st_atime_sec;
    private long    st_atime_nsec;
    private long    st_mtime_sec;
    private long    st_mtime_nsec;
    private long    st_ctime_sec;
    private long    st_ctime_nsec;
    private long    st_birthtime_sec;

    //
}

使用第三方库是可以接受的(并且是可取的),以防无法以普通方式做到这一点 Java。

在JDK中,从Java土地到fstat函数的唯一内置桥梁是sun.nio.fs.UnixFileAttributes.get()方法。这是私有的 API,只能使用反射调用。但它适用于 OpenJDK 从 7 到 14 的所有版本。

    public static PosixFileAttributes getAttributes(FileDescriptor fd)
            throws ReflectiveOperationException {

        Field f = FileDescriptor.class.getDeclaredField("fd");
        f.setAccessible(true);

        Class<?> cls = Class.forName("sun.nio.fs.UnixFileAttributes");
        Method m = cls.getDeclaredMethod("get", int.class);
        m.setAccessible(true);

        return (PosixFileAttributes) m.invoke(null, f.get(fd));
    }

    public static void main(String[] args) throws Exception {
        try (RandomAccessFile raf = new RandomAccessFile(args[0], "r")) {
            PosixFileAttributes attr = getAttributes(raf.getFD());
            System.out.println(attr.permissions());
        }
    }

其他可能的解决方案将涉及本机库 (JNI/JNA/JNR-FFI)。但是您仍然需要使用反射或 JNI 从 FileDescriptor 对象获取本机 fd。