How do I programmatically change file permissions?
In Java, I’m dynamically creating a set of files and I’d like to change the file permissions on these files on a linux/unix file system. I’d like to be able to execute the Java equivalent of chmod . Is that possible Java 5? If so, how? I know in Java 6 the File object has setReadable() / setWritable() methods. I also know I could make a system call to do this, but I’d like to avoid that if possible.
Note for others: For existing files, since Java 7, you can use this one-liner: Files.setPosixFilePermissions(path, PosixFilePermissions.fromString(«rwxr-x—«))
12 Answers 12
Full control over file attributes is available in Java 7, as part of the «new» New IO facility (NIO.2). For example, POSIX permissions can be set on an existing file with setPosixFilePermissions() , or atomically at file creation with methods like createFile() or newByteChannel() .
You can create a set of permissions using EnumSet.of() , but the helper method PosixFilePermissions.fromString() will uses a conventional format that will be more readable to many developers. For APIs that accept a FileAttribute , you can wrap the set of permissions with with PosixFilePermissions.asFileAttribute() .
Set ownerWritable = PosixFilePermissions.fromString("rw-r--r--"); FileAttribute permissions = PosixFilePermissions.asFileAttribute(ownerWritable); Files.createFile(path, permissions);
In earlier versions of Java, using native code of your own, or exec -ing command-line utilities are common approaches.
I seriously cannot believe that it’s been over six years since they started working on NIO.2 and it’s still not in a shipping JRE.
This answer stackoverflow.com/a/32331442/290182 by @PixelsTech is superior since it provides example code
Prior to Java 6, there is no support of file permission update at Java level. You have to implement your own native method or call Runtime.exec() to execute OS level command such as chmod.
Starting from Java 6, you can use File.setReadable()/File.setWritable()/File.setExecutable() to set file permissions. But it doesn’t simulate the POSIX file system which allows to set permission for different users. File.setXXX() only allows to set permission for owner and everyone else.
Starting from Java 7, POSIX file permission is introduced. You can set file permissions like what you have done on *nix systems. The syntax is :
File file = new File("file4.txt"); file.createNewFile(); Set perms = new HashSet<>(); perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_WRITE); Files.setPosixFilePermissions(file.toPath(), perms);
This method can only be used on POSIX file system, this means you cannot call it on Windows system.
For details on file permission management, recommend you to read this post.
In addition to erickson’s suggestions, there’s also jna, which allows you to call native libraries without using jni. It’s shockingly easy to use, and I’ve used it on a couple of projects with great success.
The only caveat is that it’s slower than jni, so if you’re doing this to a very large number of files that might be an issue for you.
Here’s a complete jna chmod example:
import com.sun.jna.Library; import com.sun.jna.Native; public class Main < private static CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class); public static void main(String[] args) < libc.chmod("/path/to/file", 0755); >> interface CLibrary extends Library
For correct error handling, CLibrary.chmod() must be declared to throw com.sun.jna.LastErrorException. That is the only thread-safe way of getting the errno value set by the chmod() call. Otherwise, you can get the success/fail status from the return value, but not the actual error code.
public static void main(String[] args) throws IOException < Path file = Paths.get("c:/touch.txt"); AclFileAttributeView aclAttr = Files.getFileAttributeView(file, AclFileAttributeView.class); System.out.println(aclAttr.getOwner()); for (AclEntry aclEntry : aclAttr.getAcl()) < System.out.println(aclEntry); >System.out.println(); UserPrincipalLookupService upls = file.getFileSystem().getUserPrincipalLookupService(); UserPrincipal user = upls.lookupPrincipalByName(System.getProperty("user.name")); AclEntry.Builder builder = AclEntry.newBuilder(); builder.setPermissions( EnumSet.of(AclEntryPermission.READ_DATA, AclEntryPermission.EXECUTE, AclEntryPermission.READ_ACL, AclEntryPermission.READ_ATTRIBUTES, AclEntryPermission.READ_NAMED_ATTRS, AclEntryPermission.WRITE_ACL, AclEntryPermission.DELETE )); builder.setPrincipal(user); builder.setType(AclEntryType.ALLOW); aclAttr.setAcl(Collections.singletonList(builder.build())); >
this works great. The only modification done was for the lookupPrincipalByName() method, I sent System.getProperty(«user.name») instead of «user». Finally it looked like upls.lookupPrincipalByName(System.getProperty(«user.name»)); Thanks for the code!
@bob.. can you give me AclFileAttributeView and UserPrincipalLookupService class.. bcz it cant resolve.. you answer seems to be working.. and i want to implement
java.nio.file.attribute.AclFileAttributeView and java.nio.file.attribute.UserPrincipalLookupService, it require jdk 1.7+ to compile and run.
I’m having the strangest result with this approach. I printed out the user, and it is my current active user. Yet I get access denied both in java, but also in windows when going to that file. I can’t currently explain what is happening.
Just to update this answer unless anyone comes across this later, since JDK 6 you can use
File file = new File('/directory/to/file'); file.setWritable(boolean); file.setReadable(boolean); file.setExecutable(boolean);
you can find the documentation on Oracle File(Java Platform SE 7). Bear in mind that these commands only work if the current working user has ownership or write access to that file. I am aware that OP wanted chmod type access for more intricate user configuration. these will set the option across the board for all users.
If you want to set 777 permission to your created file than you can use the following method:
public void setPermission(File file) throws IOException < Setperms = new HashSet<>(); perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_WRITE); perms.add(PosixFilePermission.OWNER_EXECUTE); perms.add(PosixFilePermission.OTHERS_READ); perms.add(PosixFilePermission.OTHERS_WRITE); perms.add(PosixFilePermission.OTHERS_EXECUTE); perms.add(PosixFilePermission.GROUP_READ); perms.add(PosixFilePermission.GROUP_WRITE); perms.add(PosixFilePermission.GROUP_EXECUTE); Files.setPosixFilePermissions(file.toPath(), perms); >
Please have a second look at the question. Roy Rico knows about setReadable() and setWritable(), but they only let you change owner permissions, not group or everyone permissions, or any of the other flags.
Apache ant chmod (not very elegant, adding it for completeness) credit shared with @msorsky
Chmod chmod = new Chmod(); chmod.setProject(new Project()); FileSet mySet = new FileSet(); mySet.setDir(new File("/my/path")); mySet.setIncludes("**"); chmod.addFileset(mySet); chmod.setPerm("+w"); chmod.setType(new FileDirBoth()); chmod.execute();
import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; import java.util.Set; public class FileAndDirectory1 < public static void main(String[] args) < File file = new File("fileTest1.txt"); System.out.println(file.getAbsoluteFile()); try < //file.createNewFile(); if(!file.exists()) < //PosixFilePermission is an enum class, PosixFilePermissions is a final class //create file permissions from string SetfilePermissions = PosixFilePermissions.fromString("---------"/* "rwxrwxrwx" */); FileAttribute permissions = PosixFilePermissions.asFileAttribute(filePermissions); Files.createFile(file.toPath(), permissions); // printing the permissions associated with the file System.out.println("Executable: " + file.canExecute()); System.out.println("Readable: " + file.canRead()); System.out.println("Writable: "+ file.canWrite()); file.setExecutable(true); file.setReadable(true); file.setWritable(true); > else < //modify permissions //get the permission using file attributes Setperms = Files.readAttributes(file.toPath(), PosixFileAttributes.class).permissions(); perms.remove(PosixFilePermission.OWNER_WRITE); perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_EXECUTE); perms.add(PosixFilePermission.GROUP_WRITE); perms.add(PosixFilePermission.GROUP_READ); perms.add(PosixFilePermission.GROUP_EXECUTE); perms.add(PosixFilePermission.OTHERS_WRITE); perms.add(PosixFilePermission.OTHERS_READ); perms.add(PosixFilePermission.OTHERS_EXECUTE); Files.setPosixFilePermissions(file.toPath(), perms); System.out.println("Executable: " + file.canExecute()); System.out.println("Readable: " + file.canRead()); System.out.println("Writable: "+ file.canWrite()); file.delete(); > > catch (IOException e) < e.printStackTrace(); >Path path = Paths.get(String.valueOf(file)); System.out.println(path); > >
private static int chmod(String filename, int mode) < try < ClassfspClass = Class.forName("java.util.prefs.FileSystemPreferences"); Method chmodMethod = fspClass.getDeclaredMethod("chmod", String.class, Integer.TYPE); chmodMethod.setAccessible(true); return (Integer)chmodMethod.invoke(null, filename, mode); > catch (Throwable ex) < return -1; >>
one should be aware that FileSystemPreferences spwans a Timer daemon thread once it’s loaded. it also adds a shutdown hook, but for some applications this may still be problematic.
File set permission java
The conversion of a pathname string to or from an abstract pathname is inherently system-dependent. When an abstract pathname is converted into a pathname string, each name is separated from the next by a single copy of the default separator character. The default name-separator character is defined by the system property file.separator , and is made available in the public static fields separator and separatorChar of this class. When a pathname string is converted into an abstract pathname, the names within it may be separated by the default name-separator character or by any other name-separator character that is supported by the underlying system.
A pathname, whether abstract or in string form, may be either absolute or relative. An absolute pathname is complete in that no other information is required in order to locate the file that it denotes. A relative pathname, in contrast, must be interpreted in terms of information taken from some other pathname. By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir , and is typically the directory in which the Java virtual machine was invoked.
The parent of an abstract pathname may be obtained by invoking the getParent() method of this class and consists of the pathname’s prefix and each name in the pathname’s name sequence except for the last. Each directory’s absolute pathname is an ancestor of any File object with an absolute abstract pathname which begins with the directory’s absolute pathname. For example, the directory denoted by the abstract pathname «/usr» is an ancestor of the directory denoted by the pathname «/usr/local/bin» .
- For UNIX platforms, the prefix of an absolute pathname is always «/» . Relative pathnames have no prefix. The abstract pathname denoting the root directory has the prefix «/» and an empty name sequence.
- For Microsoft Windows platforms, the prefix of a pathname that contains a drive specifier consists of the drive letter followed by «:» and possibly followed by «\\» if the pathname is absolute. The prefix of a UNC pathname is «\\\\» ; the hostname and the share name are the first two names in the name sequence. A relative pathname that does not specify a drive has no prefix.
Instances of this class may or may not denote an actual file-system object such as a file or a directory. If it does denote such an object then that object resides in a partition. A partition is an operating system-specific portion of storage for a file system. A single storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may contain multiple partitions. The object, if any, will reside on the partition named by some ancestor of the absolute form of this pathname.
A file system may implement restrictions to certain operations on the actual file-system object, such as reading, writing, and executing. These restrictions are collectively known as access permissions. The file system may have multiple sets of access permissions on a single object. For example, one set may apply to the object’s owner, and another may apply to all other users. The access permissions on an object may cause some methods in this class to fail.
Instances of the File class are immutable; that is, once created, the abstract pathname represented by a File object will never change.
Interoperability with java.nio.file package
The java.nio.file package defines interfaces and classes for the Java virtual machine to access files, file attributes, and file systems. This API may be used to overcome many of the limitations of the java.io.File class. The toPath method may be used to obtain a Path that uses the abstract path represented by a File object to locate a file. The resulting Path may be used with the Files class to provide more efficient and extensive access to additional file operations, file attributes, and I/O exceptions to help diagnose errors when an operation on a file fails.
java set file permissions to 777 while creating a file object [duplicate]
How do you set file permissions to 777(or any other arbitrary permission) while creating a file object in java?
In JDK7 you can use Files.setPosixFilePermissions to change the file permissions to whatever you want. If you need the permissions set atomically when creating the file then you can do that too.
3 Answers 3
Java SE 7 has java.nio.file.attribute.PosixFileAttributes which gives you fine grained control over read, write, and execute permissions for owner, group, and others.
import java.nio.file.*; import java.nio.file.attribute.*; import java.util.Set; public class Test < public static void main(String[] args) throws Exception < Path path = Paths.get("/tmp/test-file.txt"); if (!Files.exists(path)) Files.createFile(path); Setperms = Files.readAttributes(path,PosixFileAttributes.class).permissions(); System.out.format("Permissions before: %s%n", PosixFilePermissions.toString(perms)); perms.add(PosixFilePermission.OWNER_WRITE); perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_EXECUTE); perms.add(PosixFilePermission.GROUP_WRITE); perms.add(PosixFilePermission.GROUP_READ); perms.add(PosixFilePermission.GROUP_EXECUTE); perms.add(PosixFilePermission.OTHERS_WRITE); perms.add(PosixFilePermission.OTHERS_READ); perms.add(PosixFilePermission.OTHERS_EXECUTE); Files.setPosixFilePermissions(path, perms); System.out.format("Permissions after: %s%n", PosixFilePermissions.toString(perms)); > >
Which can then be used like:
$ rm -f /tmp/test-file.txt && javac Test.java && java Test Permissions before: rw-r--r-- Permissions after: rwxrwxrwx