Warm tip: This article is reproduced from serverfault.com, please click

What is the java.nio.file.Files equivalent of java.io.File.setWritable()?

发布于 2020-11-29 16:42:10

The java.io.File.setWritable() method allows you to set a file to be writable for everybody on filesystems that support this in a platform independent way.

https://docs.oracle.com/javase/7/docs/api/java/io/File.html#setWritable(boolean,%20boolean)

What allows the equivalent behaviour on the java.nio.file.Path object?

The static method java.nio.file.Files.setAttribute() implies that it is possible to set permissions,

But there is no clear set of parameters that emulate the java.io.File.setWritable() method.

https://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#setAttribute(java.nio.file.Path,%20java.lang.String,%20java.lang.Object,%20java.nio.file.LinkOption...)

Questioner
Graham Leggett
Viewed
0
rmunge 2020-11-30 03:45:40

NIO extends Java's IO but it is not a full replacement of existing classes. The java.io.File class is also not deprecated. For java.io.File.setWritable() there's no equivalent within java.nio.file.Files. As already mentioned in a previous answer, you can still convert the Path object to a File object and call setWritable.

NIO introduces the notion of file attribute views and allows to access for example also Access Control Lists (ACLs) and user defined file attributes. E.g. on Windows setWritable has only an effect on the read-only flag (first tab within file explorer) but no effect on ACLs (see the security tab in the file explorer). Even when you call file.setWritable(false) the owner will still have permissions to write but finally cant write due to the set read-only flag.

Since not all operating systems are POSIX-compatible (greets to Redmond;-) not all file attributes views are available on all operating systems. The following code would more or less do the same as java.io.File.setWritable:

public static boolean setWriteable(Path path, boolean writeable) {

    try {
        PosixFileAttributeView posix = Files.getFileAttributeView(path, PosixFileAttributeView.class);

        if (posix != null) {

            // POSIX
            Set<PosixFilePermission> permissions = new HashSet<>(posix.readAttributes().permissions());
            boolean changed = false;
            if (writeable) {
                changed = permissions.add(PosixFilePermission.OWNER_WRITE);
            } else {
                changed = permissions.remove(PosixFilePermission.OWNER_WRITE);
            }

            if (changed) {
                posix.setPermissions(permissions);
            }
            return true;

        } else {

            // Windows - does not support POSIX file permission view
            DosFileAttributeView dos = Files.getFileAttributeView(path, DosFileAttributeView.class);
            if (dos != null) {
                dos.setReadOnly(!writeable);
            }
            return true;
        }
        
    } catch (IOException e) {
        return false;
    }
}

So, if you just want to change the read-only flag of a file I would stay with File.setWritable. Its simple and you do not have to care about the operating system / supported file attribute views. If you should need more (e.g. change the owner / group for a file or read/change ACLs) file attribute views should be your choice.