Explain Codes LogoExplain Codes Logo

How do I programmatically change file permissions?

java
file-permissions
nio-2
posix-file-permissions
Anton ShumikhinbyAnton Shumikhin·Feb 13, 2025
TLDR

To change file permissions programmatically in Java, you can use Files.setPosixFilePermissions(). It's applicable for UNIX-like systems:

import java.nio.file.*; import java.nio.file.attribute.PosixFilePermission; import java.util.*; Path path = Paths.get("/your/file.txt"); Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-r-----"); Files.setPosixFilePermissions(path, perms);

Replace /your/file.txt with your file's path. You can define perms with a POSIX permissions string, like "rw-r-----" representing owner-read/write, group-read.

Java 7+: Total control over file permissions

In Java 7 and beyond, the NIO.2 provides a rich set of features for managing file attributes, enabling developers to also specify permissions during file creation.

Creating a file with defined permissions

Files.createFile() in tandem with PosixFilePermissions.asFileAttribute() can be used to create a file and set permissions atomically:

Path newPath = Files.createFile(path, PosixFilePermissions.asFileAttribute(perms)); // "Atomic" here, not related to nuclear reactions.

For a readable format, use EnumSet.of() to specify permissions numerically:

Set<PosixFilePermission> permissions = EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE); // Yes, we do speak in code, don't we Bit-man? Path newPath = Files.createFile(path, PosixFilePermissions.asFileAttribute(permissions)););

Yours, mine, and ACLs

AclFileAttributeView is supported on platforms with Access Control Lists (ACLs), providing a fine-grained control over file permissions:

AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); // With great view comes great responsibility. UserPrincipal user = FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName("username"); AclEntry entry = AclEntry.newBuilder().setType(AclEntryType.ALLOW).setPrincipal(user).setPermissions(AclEntryPermission.READ_DATA, AclEntryPermission.WRITE_DATA).build(); // Allowing "username" in, no secret handshake required. List<AclEntry> acl = view.getAcl(); acl.add(entry); view.setAcl(acl); // Now the "username" is officially part of the club.

Stand strong with older Java versions

Java 6 and earlier versions don't provide as powerful of a handle over permissions as Java 7 and above. Instead, basic methods setReadable(), setWritable(), setExecutable() should be leveraged. Note, these methods aren't as granular as the chmod command.

In these older times, programmers may resort to invoking Runtime.exec() to execute system-level commands directly or use the Java Native Access (jna) library to interface with native code capabilities, albeit with trade-offs on compatibility and security.

Advanced permission management and potential hurdles

Emulating chmod with jna

For cases where Java's own capabilities aren't just cutting it, using the Java Native Access (jna) library might help emulate chmod:

import com.sun.jna.Native; import com.sun.jna.Library; public interface CLibrary extends Library { int chmod(String path, int mode); } // Usage CLibrary libc = (CLibrary)Native.loadLibrary("c", CLibrary.class); libc.chmod("/path/to/file", 0755); // Keep calm and chmod on.

However, do note that direct usage of native libraries can introduce dependencies based on platform and have potential security implications. It's typically best to avoid natives, unless thoroughly evaluated for your scenario.

Staying flexible with permissions

Java facilitates adjusting permissions dynamically with HashSet:

Set<PosixFilePermission> dynamicPerms = new HashSet<>(); dynamicPerms.add(PosixFilePermission.OWNER_READ); dynamicPerms.add(PosixFilePermission.OWNER_WRITE); // "dynamicPerms", 'cause who doesn't like dynamism. Files.setPosixFilePermissions(path, dynamicPerms);

Keep in mind that any dynamic permission change should also ensure the current user has the appropriate rights to perform the changes, avoiding any unexpected AccessDeniedException.

Tweaking permissions your way with EnumSet

EnumSet.of() provides a way to specify permissions in an intelligible manner, reducing the chances of messing up numeric modes:

Set<PosixFilePermission> detailedPerms = EnumSet.of( PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.GROUP_READ ); Files.setPosixFilePermissions(path, detailedPerms);

This method comes handy when you want to control access level to a T.