如何以编程方式更改文件权限?

Roy*_*ico 107 java filesystems

在Java中,我正在动态创建一组文件,我想在linux/unix文件系统上更改这些文件的文件权限.我希望能够执行Java等价物chmod.这可能是Java 5吗?如果是这样,怎么样?

我知道Java 6中的File对象有setReadable()/ setWritable()方法.我也知道我可以打电话来做这件事,但如果可能的话,我想避免这样做.

eri*_*son 104

作为"新"新IO工具(NIO.2)的一部分,Java 7中提供了对文件属性的完全控制.例如,POSIX权限可以在现有文件上设置setPosixFilePermissions(),或者在文件创建时使用createFile()或等方法设置newByteChannel().

您可以使用创建一组权限EnumSet.of(),但是辅助方法PosixFilePermissions.fromString()将使用一种对许多开发人员更具可读性的传统格式.对于接受a的API FileAttribute,您可以使用with包装权限集PosixFilePermissions.asFileAttribute().

Set<PosixFilePermission> ownerWritable = PosixFilePermissions.fromString("rw-r--r--");
FileAttribute<?> permissions = PosixFilePermissions.asFileAttribute(ownerWritable);
Files.createFile(path, permissions);
Run Code Online (Sandbox Code Playgroud)

在早期版本的Java中,使用您自己的本机代码或exec-ing命令行实用程序是常用方法.

  • 代码示例可能对您的答案有用. (8认同)
  • 选择这个,因为我没有能力使用Marty Lamb的答案. (3认同)
  • @PixelsTech的答案http://stackoverflow.com/a/32331442/290182是优越的,因为它提供了示例代码 (2认同)

Mar*_*amb 42

除了erickson的建议之外,还有jna,它允许您在不使用jni的情况下调用本机库.它使用起来非常简单,我已经在几个项目中使用它并取得了巨大的成功.

唯一需要注意的是,它比jni要慢,所以如果你对大量的文件这样做可能会对你造成问题.

(编辑添加示例)

这是一个完整的jna chmod示例:

import com.sun.jna.Library;
import com.sun.jna.Native;

public class Main {
    private static CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class);

    public static void main(String[] args) {
        libc.chmod("/path/to/file", 0755);
    }
}

interface CLibrary extends Library {
    public int chmod(String path, int mode);
}
Run Code Online (Sandbox Code Playgroud)

  • JNA 是一个非常好的本地调用工具! (2认同)
  • 为了正确处理错误,必须声明CLibrary.chmod()以抛出com.sun.jna.LastErrorException.这是获得chmod()调用设置的errno值的唯一线程安全方法.否则,您可以从返回值获取成功/失败状态,但不能获取实际的错误代码. (2认同)

Pix*_*ech 28

在Java 6之前,Java级别不支持文件权限更新.您必须实现自己的本机方法或调用Runtime.exec()以执行操作系统级别命令,例如chmod.

从Java 6开始,您可以使用File.setReadable()/File.setWritable()/File.setExecutable()设置文件权限.但它不模拟允许为不同用户设置权限的POSIX文件系统.File.setXXX()仅允许为所有者和其他所有人设置权限.

从Java 7开始,引入了POSIX文件权限.您可以设置文件权限,就像您在*nix系统上所做的那样.语法是:

File file = new File("file4.txt");
file.createNewFile();

Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);

Files.setPosixFilePermissions(file.toPath(), perms);
Run Code Online (Sandbox Code Playgroud)

此方法只能用于POSIX文件系统,这意味着您无法在Windows系统上调用它.

有关文件权限管理的详细信息,建议您阅读此文章.


bob*_*bob 18

对于带有nio 2.0的Windows 7:

public static void main(String[] args) throws IOException
{
    Path file = Paths.get("c:/touch.txt");
    AclFileAttributeView aclAttr = Files.getFileAttributeView(file, AclFileAttributeView.class);
    System.out.println(aclAttr.getOwner());
    for(AclEntry aclEntry : aclAttr.getAcl()){
        System.out.println(aclEntry);
    }
    System.out.println();

    UserPrincipalLookupService upls = file.getFileSystem().getUserPrincipalLookupService();
    UserPrincipal user = upls.lookupPrincipalByName(System.getProperty("user.name"));
    AclEntry.Builder builder = AclEntry.newBuilder();       
    builder.setPermissions( EnumSet.of(AclEntryPermission.READ_DATA, AclEntryPermission.EXECUTE, 
            AclEntryPermission.READ_ACL, AclEntryPermission.READ_ATTRIBUTES, AclEntryPermission.READ_NAMED_ATTRS,
            AclEntryPermission.WRITE_ACL, AclEntryPermission.DELETE
    ));
    builder.setPrincipal(user);
    builder.setType(AclEntryType.ALLOW);
    aclAttr.setAcl(Collections.singletonList(builder.build()));
}
Run Code Online (Sandbox Code Playgroud)

  • 这很好用。所做的唯一修改是针对 lookupPrincipalByName() 方法,我发送了 System.getProperty("user.name") 而不是 "user"。最后它看起来像 upls.lookupPrincipalByName(System.getProperty("user.name")); 感谢您的代码! (2认同)

小智 11

只是为了更新这个答案,除非以后有人遇到这个,因为 JDK 6 你可以使用

File file = new File('/directory/to/file');
file.setWritable(boolean);
file.setReadable(boolean);
file.setExecutable(boolean);
Run Code Online (Sandbox Code Playgroud)

您可以在 Oracle File(Java Platform SE 7)上找到文档。请记住,这些命令仅在当前工作用户拥有该文件的所有权或写入权限时才起作用。我知道 OP 需要 chmod 类型的访问权限以进行更复杂的用户配置。这些将为所有用户设置全面的选项。


小智 9

如果要为创建的文件设置777权限,则可以使用以下方法:

public void setPermission(File file) throws IOException{
    Set<PosixFilePermission> perms = new HashSet<>();
    perms.add(PosixFilePermission.OWNER_READ);
    perms.add(PosixFilePermission.OWNER_WRITE);
    perms.add(PosixFilePermission.OWNER_EXECUTE);

    perms.add(PosixFilePermission.OTHERS_READ);
    perms.add(PosixFilePermission.OTHERS_WRITE);
    perms.add(PosixFilePermission.OTHERS_EXECUTE);

    perms.add(PosixFilePermission.GROUP_READ);
    perms.add(PosixFilePermission.GROUP_WRITE);
    perms.add(PosixFilePermission.GROUP_EXECUTE);

    Files.setPosixFilePermissions(file.toPath(), perms);
}
Run Code Online (Sandbox Code Playgroud)