以下代码为群组G-Test的文件夹“\\ myShare \ Folder1 \”设置“读取”权限:
String gName="G-Test";
AclEntryPermission[] aeps=new AclEntryPermission[]{
AclEntryPermission.READ_DATA,
AclEntryPermission.READ_ATTRIBUTES,
AclEntryPermission.READ_NAMED_ATTRS,
AclEntryPermission.READ_ACL,
AclEntryPermission.SYNCHRONIZE
};
Path p = FileSystems.getDefault().getPath(new File("\\\\myShare\\Folder1\\").getPath());
AclFileAttributeView view = Files.getFileAttributeView(p, AclFileAttributeView.class);
Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
for (AclEntryPermission acp: aeps) set.add(acp);
AclEntry.Builder b= AclEntry.newBuilder();
b.setType(AclEntryType.ALLOW);
b.setPermissions(set);
b.setPrincipal(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName(gName));
b.setFlags(new AclEntryFlag[]{AclEntryFlag.FILE_INHERIT,AclEntryFlag.DIRECTORY_INHERIT});
List<AclEntry> acl = view.getAcl();
acl.add(b.build());
view.setAcl(acl);
这适用于folder1按预期方式。但是在Folder2(子文件夹:\\ myShare \ Folder1 \ Folder2)上,ACL不会被继承。使用Windows GUI查看Folder2中缺少继承的ACL。
当使用Windows更改ACL以获取Folder1中的另一个组/权限时,我可以在folder2上看到先前缺少的权限。或者在创建新的子文件夹时,ACL是正确的继承。
上面的代码有问题吗?我想在folder1上设置Read-Permissions,它继承了所有子文件夹和文件。
代码在Windows 8.1 PC上运行,共享是Windows 2008 R2文件 - 群集
答案 0 :(得分:2)
您的代码运行正常。我有一个几乎相同的结构来设置我的环境中的权限,它也适用于那里。问题是修改权限时Folder2已存在。某些Windows API调用会在目录树中传播更改,而有些则不会(请参阅this question的答案)。 JRE必须使用其中之一。我想,你必须自己走树去传播这些变化。但是,如果在设置权限后创建Folder2,那么它将具有从顶部继承的权限(至少它是在我的上面)。
编辑: 我更多地考虑了这个问题,并认为我将来也可能需要走树。由于我们在这里谈论Java 7,我寻找一种比以前更容易走树的方法。事实证明,Files.walkFileTree()方法只是票证!我想出了这个,虽然我会分享它:
private void grantAccess(final UserPrincipal user, Path folder) {
try {
Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
grant(dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
grant(file);
return FileVisitResult.CONTINUE;
}
private void grant(Path p) throws IOException {
AclFileAttributeView view = Files.getFileAttributeView(p, AclFileAttributeView.class);
AclEntry accessEntry = createAccessACLEntry(user);
List<AclEntry> acl = view.getAcl();
acl.add(0, accessEntry); // insert at head in case there are any DENY entries
view.setAcl(acl);
}
private AclEntry createAccessACLEntry(UserPrincipal user) {
AclEntry entry = AclEntry
.newBuilder()
.setType(AclEntryType.ALLOW)
.setPrincipal(user)
.setPermissions(AclEntryPermission.DELETE_CHILD,
AclEntryPermission.WRITE_NAMED_ATTRS,
AclEntryPermission.EXECUTE,
AclEntryPermission.WRITE_DATA,
AclEntryPermission.WRITE_ATTRIBUTES,
AclEntryPermission.READ_ATTRIBUTES,
AclEntryPermission.APPEND_DATA,
AclEntryPermission.READ_DATA,
AclEntryPermission.READ_NAMED_ATTRS,
AclEntryPermission.READ_ACL,
AclEntryPermission.SYNCHRONIZE,
AclEntryPermission.DELETE)
.setFlags(AclEntryFlag.FILE_INHERIT,
AclEntryFlag.DIRECTORY_INHERIT)
.build();
return entry;
}
});
} catch (IOException e) {
throw new IllegalStateException("Unable to grant access for " + folder.toString() + " to " + user.getName(), e);
}
}
您必须覆盖visitFile()和preVisitDirectory(),以便更改文件和文件夹的权限,但您可以将postVisitDirectory()替换为preVisitDirectory()。