Set file permission in Java
Prior to Java 6, there is no good solution at the Java level to provide file permission management. You need to implement your own native methods or call the Runtime.exec() to invoke the system routine such as chmod in LInux. Since Java 6, Java introduces a set of methods which can be used to set the file permission at Java level. These methods include:
File.setReadable(boolean); File.setWritable(boolean); FIle.setExecutable(boolean); File.setReadable(boolean, boolean); File.setWritable(boolean, boolean); FIle.setExecutable(boolean, boolean);
Here File.setReadable(boolean, true) is the same as File.setReadable(boolean) which set the permission for owner only. The two argument method provides some flexibility so that you can set the permission for the owner and everyone else. The second argument of the two argument method determines whether the permission applies to the owner only. If it's false, it will apply to everyone including the owner, otherwise, it will only apply to the owner.
Let's first create a normal file with default file permission, i.e, we don't set the file permission explicitly. The example is ran on Ubuntu which can demonstrate the file permission concept better.
File file = new File("file1.txt"); file.createNewFile();
This program will create a file named file1.txt, let's see the file permission,
This file has a permission -rw-rw-r--(664), which means the owner and the users in group pike can read and write the file but cannot execute the file. While all other users can only read the file. Why this permission? This relates to the umask we set for the Ubuntu system we are using. In short, umask defines a set of permissions that applications cannot set on files. Here the umask is 0002. Java will create file without execute permission by default, so a file created with Java will have permission 666 before applying the system umask. The final file permission can be calculated as (application default permission - umask). That's why we see file1.txt has the final permission of 664.
Then let's explicitly set the file permission so that only the owner can read and write the file, all other users don't have any permission on this file. We may have below code:
File file = new File("file2.txt"); file.createNewFile(); file.setReadable(true, true); // Only the owner can read file.setWritable(true, true); // Only the owner can write
Now, let's take a look at what the permission of file2.txt is :
Unfortunately, the file permission is still rw-rw-r--(664), this is not an expected result. This is because when you call File.setXXX(), it will not clear all the permissions first, it just set the requested permission. In above case, it just sets permission for owner and it doesn't care about permissions for other users.
To get the expected result, you need to first clear all permissions for all users. Hence the correct way of achieving the above request is below code:
File file = new File("file3.txt"); file.createNewFile(); // Clear all permissions for all users file.setReadable(false, false); file.setWritable(false, false); file.setExecutable(false, false); file.setReadable(true, true); // Only the owner can read file.setWritable(true, true); // Only the owner can write
file3.txt will be created with below permission:
Since Java 7, a new way of setting file permission is introduced with the introduction of Java Non-Blocking IO. The new way copies the idea from the permission management system from POSIX based system. That is, it will allow users to set permissions for owner, group and others just like what you can do on *nix based system. This gives more flexibility over Java 6 on how file permission can be set.
The new permission class is called PosixFilePermission and below is a demo on how to set the permission this way. We still try to set the permission that only owner can read and write the file.
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);
Here is file4.txt's file permission:
Note, the new way can only be used on file systems which support POSIX file system. Otherwise, a java.lang.UnsupportedOperationException will be thrown. For example, if you run the above code on a Windows system, you will see above exception.
Final words : to be cross platform compatible, you should combine the above ways of setting file permission in your application so that there is a fallback mechanism. For some applications where file permission should be strictly controlled, for example security applications, you may even need to use the native methods.
When two cars are competing for the same lane, the unexpected happens.