在Linux下使用java.nio.Files更改文件所有者组

19

我有一个Linux服务器,并在服务器上为多个网站运行Java图像调整作业。网站文件由不同的操作系统用户/组拥有。新创建的缩略图/预览由运行调整作业的用户拥有。现在我正在谷歌搜索如何在我的调整程序中更改新创建的预览/缩略图的文件所有者,并找到了这个:

java.nio.file.Files.setOwner(Path path, UserPrincipal owner);

如果这是Windows系统,那么这个方法就可以解决我的问题,但由于Linux文件有一个用户和组作为所有者,所以我有点麻烦。不幸的是,给定的方法似乎只能更改文件的用户所有权,而组所有权仍然归属于运行我的Java调整大小作业的用户组。

这些网站归不同的组所有,因此将我的调整大小作业用户添加到其中一个组是不可行的。我还想避免使用ProcessBuilder进行系统调用并在我的文件上执行chown操作。

我需要指出的是,创建的文件(预览/缩略图)可以通过网站访问,并且更改组所有权对任务完成并非至关重要,但我希望尽可能地保持清洁。

有什么建议可以仅使用Java在Linux中更改文件的组所有权吗?

4个回答

34

感谢Jim Garrison把我指向了正确的方向。这是最终为我解决问题的代码。

检索文件的组所有者

File originalFile = new File("original.jpg"); // just as an example
GroupPrincipal group = Files.readAttributes(originalFile.toPath(), PosixFileAttributes.class, LinkOption.NOFOLLOW_LINKS).group();

设置文件的群组所有者

File targetFile = new File("target.jpg");
Files.getFileAttributeView(targetFile.toPath(), PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS).setGroup(group);

4
如果您没有可用于查找的文件,可以使用以下方法按名称获取组:UserPrincipalLookupService.lookupPrincipalByGroupName(java.lang.String)。 - Paul Gregoire
1
为了进一步解释Paul的评论,您需要以下内容:UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService(); 然后,GroupPrincipal targetGroupPrincipal = lookupService.lookupPrincipalByGroupName(targetGroupName); - Software Prophets

18

我错过了一个完整的解决方案,现在它来了(结合其他答案和评论):

Path p = Paths.get("your file's Path");
String group = "GROUP_NAME";
UserPrincipalLookupService lookupService = FileSystems.getDefault()
                .getUserPrincipalLookupService();
GroupPrincipal group = lookupService.lookupPrincipalByGroupName(group);
Files.getFileAttributeView(p, PosixFileAttributeView.class,
                LinkOption.NOFOLLOW_LINKS).setGroup(group);

请注意,只有文件的所有者才能更改其所属组,并且只能更改到他所属的组...


4
最后一句的替代语句:Files.setAttribute(p,"posix:group",group,LinkOption.NOFOLLOW_LINKS); 的备选方案: - 200_success
2
你可能想要指定你的示例是伪代码,或将String group = "GROUP_NAME"更改为final String GROUP = "GROUP_NAME",因为存在与GroupPrincipal group冲突的情况。乍一看,我以为GroupPrincipal group在实例化过程中通过lookupService.lookupPrincipalByGroupName(group)引用了它自己。 - Jonny Henly

3

请看java.nio.file.attributesPosixFilePermissions类的包。这是您可以操作组权限的地方。


1

此次回应的目的是将对原帖的回应中所收到的评论之一提升为正式回应级别,以便更突出地显示。

以下是我们采用的方法:

//  newUser and newGroup are strings. 

UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
UserPrincipal userPrincipal = lookupService.lookupPrincipalByName(newUser);
GroupPrincipal groupPrincipal = lookupService.lookupPrincipalByGroupName(newgroup);

Files.setAttribute(filePath, "posix:owner", userPrincipal, LinkOption.NOFOLLOW_LINKS);
Files.setAttribute(filePath, "posix:group", groupPrincipal, LinkOption.NOFOLLOW_LINKS);

此外,我们不得不以超级用户身份运行Java程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接