【问题标题】:How to check file permissions in Java (OS independently)如何在 Java 中检查文件权限(独立于操作系统)
【发布时间】:2012-06-02 18:19:21
【问题描述】:

我有以下sn-p的代码:

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!!!!!");
}
}

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

【问题讨论】:

  • 它如何在 Windows 7 上“不起作用”?
  • 什么确切地说不起作用?
  • 告诉你在运行上面的代码时得到什么文件权限的输出。没有那个什么都做不了。
  • 方法 canXXX 始终返回 true,即使不应该返回。
  • 你检查你的程序没有扩展权限吗?为什么你说它不应该返回 true ?以后在读或写时会出错吗?

标签: java file-permissions


【解决方案1】:

这可能是由某些东西(例如防病毒产品)以不一致的方式“调解”文件访问造成的。

当然,很难相信 Java File.canXxxx() 方法通常在任何风格的 Windows 上都被破坏了。


更新 - 我收回了。阅读this Sun bug report ...然后哭泣。简短的回答是这是一个 Windows 错误,Sun 决定不解决它。 (但是新的 Java 7 API 确实可以工作......)

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

【讨论】:

  • 但确实如此,File.canExecute() 返回 true,而在 cmd 中执行文件 (.bat) 时返回“拒绝访问”
  • 我已经测试了链接中的代码,发现在jdk 1.7.0_79中没有这个bug了。当我将文件设置为无法写入并在 Windows 10 资源管理器中隐藏时,代码显示它无法写入并且按预期隐藏。所以我认为它在 Java 7 中已修复。
【解决方案2】:

我已经对 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))
            ...
    }
}

JDK:1.7.0_25、1.8.0_91

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

【讨论】:

    【解决方案3】:

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

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

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

    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();
      
      
          }
      
      }
      

    我明白了:

    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
    

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

    注意文件是可读的,setReadable(false)返回false,文件还是可读的。 JavaDoc 说here setReadable() 返回false 当用户无权更改访问权限时,或者当readable 已经是false,并且底层系统没有对此的实现。调试到 Java API 并没有提供太多信息,因为实现标记为 native 并且看不到更多信息。但是我有权更改可写性,所以我不明白。

    但也请注意,java.util.File 不支持更多属性,例如 setHidden()。或许你可以查看java.security中的其他包,比如AccessController

    【讨论】:

      猜你喜欢
      • 2013-06-14
      • 2010-09-14
      • 2017-11-06
      • 2017-07-19
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多