在目录中创建文件之前检查目录中的写访问权限

Posted

技术标签:

【中文标题】在目录中创建文件之前检查目录中的写访问权限【英文标题】:Checking for write access in a directory before creating files inside it 【发布时间】:2010-11-19 07:37:51 【问题描述】:

我的小型实用应用程序通过 GUI 文件选择器向用户询问输出目录。 然后它经过一些处理在这个输出目录中创建了很多文件。

我需要检查应用程序是否具有写入权限,以便通知用户并执行 不继续处理(可能需要很长时间)

我的第一次尝试是 java.io.FilecanWrite() 方法。但这不起作用 因为它处理目录条目本身而不是其内容。我至少见过 可以重命名或删除但不能创建文件的 Windows XP 文件夹的一个实例 在其中(因为权限)。这实际上是我的测试用例。

我终于用下面的解决方案解决了

//User places the input file in a directory and selects it from the GUI
//All output files will be created in the directory that contains the input file
File fileBrowse = chooser.getSelectedFile(); //chooser is a JFileChooser
File sample = new File(fileBrowse.getParent(),"empty.txt"); 
try

     /*
      * Create and delete a dummy file in order to check file permissions. Maybe 
      * there is a safer way for this check.
      */
      sample.createNewFile();
      sample.delete();

catch(IOException e)

      //Error message shown to user. Operation is aborted

然而这对我来说并不优雅,因为它只是尝试实际创建一个文件并检查操作是否成功。

我怀疑必须有更好的方法,但到目前为止我找到的所有解决方案 与安全管理器一起处理 Java Applet 而不是独立应用程序。 我错过了什么吗?

在之前检查目录内文件访问的推荐方法是什么 真的在写文件吗?

我正在使用 Java 5。

【问题讨论】:

如果“empty.txt”已经存在怎么办?然后你最终删除了一个可能很重要的文件。 是的,最好使用 createNewFile() 返回的布尔值来了解文件是否实际创建。 【参考方案1】:

即使在最终路径上调用canWrite 也不起作用?

File sample = new File(fileBrowse.getParent(),"empty.txt"); 

if (sample.canWrite()) 
    doSomethingUseful(sample);
 else 
    notifyUser();

【讨论】:

它不会,因为 canWrite 也会检查文件是否存在。您的代码并非如此。它在javadoc中提到。【参考方案2】:

您可以使用FilePermission 获取详细信息。 我找到了一种需要实现SecurityManager 的方法,代码是here 和here

【讨论】:

我查看了 FilePermission,但在我看来,它在 Applets 中用于授予对文件的访问权限。您有独立应用程序的示例吗?【参考方案3】:

您可以检查文件权限,确保目录存在,并进行大量检查或找到一个库来为您完成所有检查但是(!)不是最好的方法检查试试?如果您检查权限并且文件系统更改......您将不得不更改您的代码。但是尝试写入文件总是会告诉您是否可以写入文件。

您的解决方案不必是最优雅的解决方案。这不是廉价的硬编码补丁或丑陋的东西。这只是普通的代码。它会一直有效。但是,如果您不喜欢在代码中看到检查,只需将其放在类中即可将其分开,唯一的目标是检查是否可以编写。事实上,不管你喜欢优雅与否,你都应该把它放在一个实用类中。

另一种解决方案是将整个写入硬盘的代码放在 try.如果你不会写,整个部分会被跳过,你会在 catch 部分给用户反馈。

【讨论】:

【参考方案4】:

使用 Java 1.8 我能够使用以下内容。

Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(Paths.get(destDir), LinkOption.NOFOLLOW_LINKS);
Assert.assertTrue("User did not have read permission.", permissions.contains(PosixFilePermission.OWNER_READ));
Assert.assertTrue("User did not have execute permission.", permissions.contains(PosixFilePermission.OWNER_EXECUTE));
Assert.assertTrue("User did not have write permission.", permissions.contains(PosixFilePermission.OWNER_WRITE));

Assert.assertFalse("Group did have read permission.", permissions.contains(PosixFilePermission.GROUP_READ));
Assert.assertFalse("Group did have execute permission.", permissions.contains(PosixFilePermission.GROUP_EXECUTE));
Assert.assertFalse("Group did have write permission.", permissions.contains(PosixFilePermission.GROUP_WRITE));

Assert.assertFalse("Others did have read permission.", permissions.contains(PosixFilePermission.OTHERS_READ));
Assert.assertFalse("Others did have execute permission.", permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
Assert.assertFalse("Others did have write permission.", permissions.contains(PosixFilePermission.OTHERS_WRITE));

【讨论】:

以上是关于在目录中创建文件之前检查目录中的写访问权限的主要内容,如果未能解决你的问题,请参考以下文章

尝试在只写目录中创建/删除/重命名文件时权限被拒绝

为啥要执行权限以及在 c(Linux) 中创建文件所需的写权限? [关闭]

Linux的权限管理:实现资源的分派

在访问和/或 DAO 中创建检查约束

在创建文件夹之前检查 VBA Access 中目录的权限

检查目录是不是存在和权限[重复]