Reputation: 359
I have the following snippet of code:
public class ExampleClass {
public static void main(String[] args) throws FileNotFoundException {
String filePath = args[0];
File file = new File(filePath);
if (!file.exists())
throw new FileNotFoundException();
if (file.canWrite())
System.out.println(file.getAbsolutePath() + ": CAN WRITE!!!");
else
System.out.println(file.getAbsolutePath() + ": CANNOT WRITE!!!!!");
if (file.canRead())
System.out.println(file.getAbsolutePath() + ": CAN READ!!!");
else
System.out.println(file.getAbsolutePath() + ": CANNOT READ!!!!!");
if (file.canExecute())
System.out.println(file.getAbsolutePath() + ": CAN EXECUTE!!!");
else
System.out.println(file.getAbsolutePath() + ": CANNOT EXECUTE!!!!!");
}
}
It works in Linux OS, but the problem is that it doesn't work in windows7. So the question is: Does anybody know a method to check privileges to a file in Java OS INDEPENDENTLY?
Upvotes: 14
Views: 33338
Reputation: 718798
It is hard to believe that the Java File.canXxxx()
methods are generally broken on any flavour of Windows.
However, read this Sun bug report ... and weep. The short answer is that it is a Windows bug, and Sun decided not to work around it. (But the new Java 7 APIs do work ...)
FWIW, I maintain that it is BAD PRACTICE to try to check file access permissions like that. It is better to simply attempt to use the file, and catch the exceptions if / when they occur. See https://stackoverflow.com/a/6093037/139985 for my reasoning. (And now we have another reason ...)
Upvotes: 10
Reputation: 12728
First of all, Java trust local files and untrust remote files by default and by design. So when testing, be aware of that what you can do in your computer at home, may be impossible in some remote drive of your company's server.
Second, when we check file permissions on remote drives, it's usually not enough just setting it in the Windows Explorer(Property... - Read only/Hide/Archive, etc. ). For example, my organization have other mechinisms to control both local and remote file permission, and even being Administrator of my PC cannot guarantee everything. Even if manually/programmatically you can change the permission of a file, if some other applications/group policy/etc forbids you to do so, the change may fail. (For example, setReadable()
returns false
, suggesting that it's not possible)For example, I can execute
a txt
file in a remote directory, meaning open it, but a bat
file in the same directory is not executable, actually, in my case, I am required to ask my admin to gain more authority when I want to create a bat
file. I think it might be that bat
extension are forbidden. Because as user in some user group in Windows, your action and JVM run by you are limited by higher rules than JVM itself. Correct me if I am wrong.
However, even if you might not be able to set the permisson of a file, now you can read them correctly in Java 7. Obviously after the bug report, Java guys had done something to fix the most of it. I am using jdk 1.7.0_19
, and to test, I have done the following:
Set the property of a remote file, in Windows Explorer, to Read Only
and Hidden
.
Read it from Java, with code below (from the link of Stephen C and modified to see setXxxxx()
methods can work).
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class FilePermissionTester {
public static void main( String[] args ) throws IOException {
File file = new File("Y:\\some\\remote\\drive\\directoy\\xxxxx.txt");
System.out.println( "exists:" + file.exists() );
System.out.println( "is file:" + file.isFile() );
System.out.println( "can read:" + file.canRead() );
System.out.println( "can execute:" + file.canExecute() );
System.out.println( "can write:" + file.canWrite() );
System.out.println( "is hidden:" + file.isHidden() );
System.out.println("change it to be unreadable, and it works? " + file.setReadable(false));
System.out.println( "can read:" + file.canRead() );
System.out.println("change it to be writable, and it works? " + file.setWritable(true));
System.out.println( "can write:" + file.canWrite() );
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read();
fileInputStream.close();
}
}
I got:
exists:true
is file:true
can read:true
can execute:true
can write:false
is hidden:true
change it to be unreadable, and it works? false
can read:true
change it to be writable, and it works? true
can write:true
And now I can read this file, edit it and save it. Before changing the permission I was asked to Save As.. when saving.
Note that the file is readable, and setReadable(false)
returns false
, and the file is still readble. JavaDoc says here that setReadable()
return false
when user haven't permission to change the access premission, or when readable
is already false
, and the underlying system doesn't have implementation for this. Debugging into Java API doesn't provide much info, because the implementation are marked native
and cannot see more. But I have the permission to change the writability, so that's something I don't understand.
But also note that there are more attributes out there that are not supported by java.util.File
, like . Maybe you can check other pacakges in setHidden()
java.security
, like AccessController?
Upvotes: 2
Reputation: 1628
I have done some tests on the NIO APIs (from Java 7) and they seem to work perfectly.
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class PermissionCheck {
public static void main(String[] args) throws FileNotFoundException {
String filePath = args[0];
Path p = Paths.get(filePath);
if (Files.notExists(p))
throw new FileNotFoundException();
if (Files.isWritable(p))
...
if (Files.isReadable(p))
...
if (Files.isExecutable(p))
...
}
}
JDKs: 1.7.0_25, 1.8.0_91
OS: Windows 7, 8 (64bit)
Upvotes: 6