如何确定为什么Windows上FIles.isWritable()返回false [英] How can you work out why FIles.isWritable() returns false on Windows
问题描述
在我的允许用户偶尔修改其音乐文件的应用程序中,当应用程序无权修改文件但用户确信他们已授予其完全权限时,我遇到了问题
In my application that allows users to modify their music files occasionally I have a problem when application does not have permissions to modify a file but the user is convinced they have given it full permissions
我发现了Java 7的改进,并编写了此方法来输出权限
I've discovered the Java 7 improvements and wrote this method to output the permissions
public static String displayPermissions(Path path)
{
StringBuilder sb = new StringBuilder();
sb.append("File "+path + " permissions\n");
try
{
{
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
if (view != null)
{
for (AclEntry acl : view.getAcl())
{
sb.append(acl+"\n");
}
}
}
{
PosixFileAttributeView view = Files.getFileAttributeView(path, PosixFileAttributeView.class);
if (view != null)
{
PosixFileAttributes pfa = view.readAttributes();
sb.append(":owner:"+pfa.owner().getName()+":group:"+pfa.group().getName()+":"+PosixFilePermissions.toString(pfa.permissions())+"\n");
}
}
}
catch(IOException ioe)
{
logger.severe("Unable to read permissions for:"+path.toString());
}
return sb.toString();
}
但是对于Windows系统来说,弄清为什么它们没有权限仍然很困难/不可能
but for Windows systems it can still be rather difficult/impossible to work out why they don't have permissions
WARNING: File testdata\test157.dsf permissions
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
,关于如何以编程方式找出isWritable()(或isReadable())失败原因的任何建议.
, any suggestions on how I can programmatically work out the reason for isWritable() (or isReadable()) failing.
推荐答案
我相信混淆来自于以下事实:有效权限取决于目录权限和文件权限.
I believe the confusion comes from the fact that the effective permission depends on the directory permissions and the file permissions.
如果用户有文件的Write
权限而不是包含目录的Modify
权限,他实际上没有对该文件的写权限.请参阅文件和文件夹权限的完整矩阵.
If the user has e.g. the Write
permission for a file but not the Modify
permission for the containing directory he has effectively not write permission to that file. See the full matix of File and folder permissions.
To do the check in Java you can use the FileSystemProvider.checkAccess method to check the permission of
假定以下文件和权限(所有超出范围的权限都将被删除,以使其更加清晰).权限是使用icacls
工具检索的.
Assume following files and permissions (all permissions out of scope are removed to make it more clear). The permissions were retrieved with the icacls
tool.
c:\ BUILTIN\Users:(OI)(CI)(RX) - read + execute permission
c:\bar BUILTIN\Users:(RX) - read + execute permission
c:\foo BUILTIN\Users:(F) - full permission
用于演示的示例代码段.
Sample snippet for demonstration.
public class AccessCheckDemo {
public static void main(String[] args) throws IOException {
String[] files = {"c:/foo", "c:/bar"};
for (String file : files) {
Path path = Paths.get(file);
System.out.println("check " + path);
System.out.println("file Files.isWritable: "
+ Files.isWritable(path));
System.out.println("directory Files.isWritable: "
+ Files.isWritable(path.getParent()));
System.out.println();
}
}
}
输出
check c:\foo
file Files.isWritable: true
directory Files.isWritable: false
check c:\bar
file Files.isWritable: true
directory Files.isWritable: false
即使BUILTIN\Users
在文件c:\foo
上具有full permissions
,它们也无法写入该文件,因为目录c:\
的权限不允许它(仅对c:\
的该组的读取+执行权限)
Even BUILTIN\Users
have full permissions
on file c:\foo
they cannot write to this file, as the permission of the directory c:\
does not permit it (only read + execute permission for this group on c:\
).
正如badsamaritan( JDK-7190897 所提到的那样)在Java 7中正常工作.
As already mentioned by badsamaritan (JDK-7190897) this doesn't work properly in Java 7.
这篇关于如何确定为什么Windows上FIles.isWritable()返回false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!