Files.exists(path)和path.toFile()。exists()为同一个文件

时间:2016-01-29 15:08:27

标签: java security nio

对于Windows上的本地文件,Files.exists(path)path.toFile().exists()的结果不同。我可以在Windows资源管理器中看到这个文件,虽然我有(随机)修改过的权限,也许权限没有意义。

但是,这并不能解释为什么旧方法返回true并且新方法返回false。该文件确定存在但可能对运行Java代码的用户不可见,因此我不确定应该是什么样的正确答案。我也无法看到如何查看哪个用户正在运行代码,计算机上只有一个真实用户保罗,但我想知道是否以管理员身份运行或不影响事情。

System.out.println("Path Exists(1):"+Files.exists(path));
System.out.println("Path Exist(2) :"+path.toFile().exists());

给出

Path Exists(1):false
Path Exist(2) :true

另外

System.out.println("Path readable(3) :"+Files.isReadable(path));
System.out.println("Path readable(4):"+path.toFile().canRead());

以同样的方式工作

Path readable(3) :false
Path readable(4):true

权限输出

File C:\Code\jthink\opensrc\jaudiotagger\testdata\test157.dsf permissions
owner:PCLAPTOP\Paul
NT AUTHORITY\SYSTEM:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:DENY
BUILTIN\Administrators:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:DENY
BUILTIN\Administrators:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:ALLOW
NT AUTHORITY\SYSTEM:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:ALLOW
BUILTIN\Users:READ_DATA/READ_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/READ_ACL/SYNCHRONIZE:ALLOW
NT AUTHORITY\Authenticated Users:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/SYNCHRONIZE:ALLOW


c:\Code\jthink\opensrc\jaudiotagger>attrib C:\Code\jthink\opensrc\jaudiotagger\testdata\test157.dsf
A    R       C:\Code\jthink\opensrc\jaudiotagger\testdata\test157.dsf

更新 我没有得出结论,但认为这些信息可能有用。

我在IntelliJ IDE中运行代码而没有启用IDE 运行程序作为管理员 选项,启用此功能后,Java应用程序也获得了管理员权限。 / p>

对于另一个文件感兴趣我没有添加任何DENY权限,我只是禁用了继承权限并从所有组中删除了READ权限。然后,当我作为用户运行而没有运行管理员启用它无法读取文件,此代码也无法输出任何信息

AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
if (view != null)
{
    sb.append("Owner:"+view.getOwner().getName()+"**");
    for (AclEntry acl : view.getAcl())
    {
        sb.append(acl.principal()+"**");
        for(AclEntryPermission aep:acl.permissions())
        {
            sb.append(aep.toString() + "**");
        }
    }
}

但是当我使用 运行程序作为管理员 启用时,它仍然无法读取该文件,但上面的代码现在输出了一些权限,如下所示:

  

所有者:BUILTIN \ Administrators

     

NT AUTHORITY \ SYSTEM:WRITE_DATA / APPEND_DATA / WRITE_NAMED_ATTRS / WRITE_ATTRIBUTES / SYNCHRONIZE:ALLOW   PCLAPTOP \保罗:WRITE_DATA / APPEND_DATA / WRITE_NAMED_ATTRS / WRITE_ATTRIBUTES /同步:ALLOW   BUILTIN \管理员:WRITE_DATA / APPEND_DATA / WRITE_NAMED_ATTRS / WRITE_ATTRIBUTES / SYNCHRONIZE:ALLOW

正如您所见,即使Administrators没有READREAD PERMISSIONS选项,他们也可以输出权限,而在他们不能之前,可能是因为BUILTIN / Administraor被返回为所有者。

2 个答案:

答案 0 :(得分:7)

试试看: https://docs.oracle.com/javase/tutorial/essential/io/check.html

它声明,Files.exists(path)返回false并不意味着它不存在,所以是的,似乎存在权限问题。尝试Files.notExists(path)并查看它返回的内容。如果为false,则表示无法确定文件是否存在,但如果返回true,则代码中可能存在一些问题。

尝试从命令行而不是netbeans运行您的文件。如果您不知道如何执行此操作,您可以只搜索谷歌,这里有很多东西,但基本上您要做的是使用javac myfile.java编译.java文件,然后使用{运行它{1}}。使用正常的命令提示符执行此操作,并以管理员身份打开并查看所获得的内容。

答案 1 :(得分:4)

这些是两种不同的方法:Files.exists()和path.toFile()。exists()。

Files.exists()定义了由此抽象路径名表示的文件。换句话说,该文件存在且用户具有READ访问权限。

path.toFile().exists()表示该文件存在,因此无法保证子序列访问将成功。换句话说,文件存在而不检查用户是否具有READ访问权限。

这实际上取决于运行该程序的用户。当你按照你的身份(保罗)工作时,它运作正常。特别是在命令行中,你可以使用ATTRIB命令。

但是,当您使用其他应用程序运行代码时,它取决于系统配置。在您的应用程序中运行此ATTRIB或类似命令,您将看到。

我认为你在IIS下运行一些网站。这种方式通常配置为系统中的最低级别用户,几乎没有权限来防止安全中断。通常是每个人或NT AUTHORITY。正如我所看到的,此特定访问权无权读取您的文件

  

NT AUTHORITY \ SYSTEM:READ_DATA / ...:DENY

当然你有2个不同的答案 - FALSE:运行应用程序使用哪个ID的用户无法读取此文件,TRUE:文件存在实际存在。

更改应用程序的运行ID,或者为此特定文件(包括其路径中的所有目录)的每个人授予READ访问权限,这两种检查不同含义的方法将产生相同的结果。