简体   繁体   中英

How to check file permissions in Java (OS independently)

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?

This might be caused by something (for instance an anti-virus product) "mediating" file access in an inconsistent way.

Certainly, it is hard to believe that the Java File.canXxxx() methods are generally broken on any flavour of Windows.


UPDATE - I take that back. 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 ...)

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)

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:

  1. Set the property of a remote file, in Windows Explorer, to Read Only and Hidden .

  2. 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 setHidden() . Maybe you can check other pacakges in java.security , like AccessController ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM