简体   繁体   English

如何在Java中检查文件权限(OS独立)

[英]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. 它适用于Linux操作系统,但问题是它在windows7中不起作用。 So the question is: Does anybody know a method to check privileges to a file in Java OS INDEPENDENTLY? 所以问题是:是否有人知道在Java OS中独立检查文件权限的方法?

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. 当然,很难相信Java File.canXxxx()方法通常会在任何类型的Windows上被破坏。


UPDATE - I take that back. 更新 - 我把它拿回来。 Read this Sun bug report ... and weep. 阅读这篇Sun bug报告 ......然后哭泣。 The short answer is that it is a Windows bug, and Sun decided not to work around it. 简短的回答是它是一个Windows错误,Sun决定不解决它。 (But the new Java 7 APIs do work ...) (但新的Java 7 API 确实有用......)

FWIW, I maintain that it is BAD PRACTICE to try to check file access permissions like that. FWIW,我认为尝试检查这样的文件访问权限是不好的做法。 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. 有关我的推理,请参阅https://stackoverflow.com/a/6093037/139985 (And now we have another reason ...) (现在我们有另一个原因......)

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位)

First of all, Java trust local files and untrust remote files by default and by design. 首先,默认情况下,Java信任本地文件和untrust远程文件。 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. ). 其次,当我们检查远程驱动器上的文件权限时,通常仅在Windows资源管理器中设置它( 属性... - 只读 / 隐藏 / 存档等)是不够的。 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. 例如,我的组织有其他机制来控制本地和远程文件权限,甚至作为我的PC的管理员也无法保证一切。 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. 即使手动/以编程方式,您可以更改文件的权限,如果某些其他应用程序/组策略/ etc禁止您这样做,则更改可能会失败。 (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. (例如, setReadable()返回false ,表明它不可能)例如,我可以在远程目录中execute txt文件,这意味着打开它,但同一目录中的bat文件不可执行,实际上,在我的如果我想创建一个bat文件,我需要让我的管理员获得更多权限。 I think it might be that bat extension are forbidden. 我认为可能禁止bat扩展。 Because as user in some user group in Windows, your action and JVM run by you are limited by higher rules than JVM itself. 因为作为Windows中某个用户组的用户,您运行的操作和JVM受限于比JVM本身更高的规则。 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. 但是,即使您可能无法设置文件的权限,现在您也可以在Java 7中正确读取它们。显然,在错误报告之后,Java人员已经做了一些事情来解决大部分问题。 I am using jdk 1.7.0_19 , and to test, I have done the following: 我使用的是jdk 1.7.0_19 ,为了测试,我做了以下工作:

  1. Set the property of a remote file, in Windows Explorer, to Read Only and Hidden . 在Windows资源管理器中将远程文件的属性设置为“ Read Only和“ Hidden

  2. Read it from Java, with code below (from the link of Stephen C and modified to see setXxxxx() methods can work). 从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. 在更改权限之前,我在保存时被要求另存为..

Note that the file is readable, and setReadable(false) returns false , and the file is still readble. 请注意,该文件是可读的,并且setReadable(false)返回false ,并且该文件仍然可读。 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. JavaDoc的说这里setReadable()返回false时用户没有权限更改访问premission,或当readable已经是false ,和底层系统没有实现这一点。 Debugging into Java API doesn't provide much info, because the implementation are marked native and cannot see more. 调试到Java API并不提供太多信息,因为实现标记native ,无法看到更多信息。 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() . 但是请注意, java.util.File不支持更多属性,例如 setHidden() Maybe you can check other pacakges in java.security , like AccessController ? 也许你可以检查java.security其他pacakges,比如AccessController

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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