如何在 Java(独立于操作系统)中检查文件权限

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10783677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:33:24  来源:igfitidea点击:

How to check file permissions in Java (OS independently)

javafile-permissions

提问by Jaros?aw Drabek

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?

它适用于 Linux 操作系统,但问题是它不适用于 windows7。所以问题是:有没有人知道一种在 Java OS 中独立检查文件权限的方法?

回答by Stephen C

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 generallybroken on any flavour of Windows.

当然,很难相信 JavaFile.canXxxx()方法在任何类型的 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 dowork ...)

更新- 我收回。阅读这份 Sun 错误报告……并哭泣。简短的回答是这是一个 Windows 错误,Sun 决定不解决它。(但新的 Java 7 API确实有效......)

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/139985for my reasoning. (And now we have another reason ...)

FWIW,我认为尝试像这样检查文件访问权限是不好的做法。最好简单地尝试使用该文件,并在它们发生时捕获异常。请参阅https://stackoverflow.com/a/6093037/139985了解我的推理。(现在我们还有另一个原因......)

回答by Linuslabo

I have done some tests on the NIO APIs (from Java 7) and they seem to work perfectly.

我已经对 NIO API(来自 Java 7)进行了一些测试,它们似乎运行良好。

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

JDK:1.7.0_25、1.8.0_91

OS: Windows 7, 8 (64bit)

操作系统:Windows 7、8(64位)

回答by WesternGun

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.

首先,Java 在默认情况下和设计上信任本地文件而不信任远程文件。因此,在测试时,请注意您在家里的计算机上可以做的事情,在您公司服务器的某些远程驱动器中可能是不可能的。

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 executea txtfile in a remote directory, meaning open it, but a batfile 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 batfile. I think it might be that batextension 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.

其次,当我们检查远程驱动器文件的权限,它通常没有足够的只是设置它在Windows资源管理器(Property...- Read only/ Hide/Archive等)。例如,我的组织有其他机制来控制本地和远程文件权限,即使是我的 PC 管理员也不能保证一切。即使您可以手动/以编程方式更改文件的权限,如果其他一些应用程序/组策略/等禁止您这样做,更改也可能会失败。(比如setReadable()returns false,提示不可能)比如我可以远程目录下的execute一个txt文件,意思是打开它,但是一个bat同一目录中的文件不可执行,实际上,就我而言,当我想创建bat文件时,我需要让我的管理员获得更多权限。我认为可能bat是禁止扩展。因为作为 Windows 中某个用户组的用户,您的操作和您运行的 JVM 受到比 JVM 本身更高的规则的限制。如果我错了,请纠正我。

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:

但是,即使您可能无法设置文件的权限,现在您也可以在 Java 7 中正确读取它们。显然,在报告错误之后,Java 人员已经做了一些事情来修复它的大部分内容。我正在使用jdk 1.7.0_19,为了测试,我做了以下事情:

  1. Set the property of a remote file, in Windows Explorer, to Read Onlyand 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();
    
    
        }
    
    }
    
  1. 在 Windows 资源管理器中将远程文件的属性设置为Read OnlyHidden

  2. 从 Java 中读取它,代码如下(来自 Stephen C 的链接并修改以查看setXxxxx()方法可以工作)。

    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.

现在我可以读取这个文件,编辑它并保存它。在更改权限之前,我Save As..在保存时被要求。

Note that the file is readable, and setReadable(false)returns false, and the file is still readble. JavaDoc says herethat setReadable()return falsewhen user haven't permission to change the access premission, or when readableis 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 nativeand cannot see more. But I have the permission to change the writability, so that's something I don't understand.

请注意,该文件是可读的,并setReadable(false)返回false,并且该文件仍然是可读的。JavaDoc的说这里setReadable()回报false的时候用户没有权限更改访问premission,或者readable是已经false和底层系统没有实现这一点。调试到 Java API 并没有提供太多信息,因为实现被标记native并且看不到更多信息。但是我有权更改可写性,所以这是我不明白的事情。

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?

但还要注意,还有更多不受 支持的属性java.util.File,例如setHidden(). 也许您可以检查其他 pacakges java.security,例如AccessController