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

在 Java 中,我动态地创建一组文件,我想在 linux/Unix文件系统上更改这些文件的文件权限。我希望能够执行与 chmod等效的 Java。有可能是 Java 5吗?如果是这样,怎么做?

我知道在 Java 6中 File对象有 setReadable()/setWritable()方法。我也知道我可以做一个系统调用来做这件事,但是如果可能的话,我想避免这样做。

214437 次浏览

在 Java7中可以对文件属性进行完全控制,这是“新的”新 IO 工具(NIO.2)的一部分。例如,可以使用 setPosixFilePermissions(),在现有文件上设置 POSIX 权限,也可以使用 createFile()newByteChannel().等方法在文件创建时自动设置 POSIX 权限

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

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

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

除了 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);
}

对于 NIO 2的 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()));
}

OralceJava6:

private static int chmod(String filename, int mode) {
try {
Class<?> fspClass = Class.forName("java.util.prefs.FileSystemPreferences");
Method chmodMethod = fspClass.getDeclaredMethod("chmod", String.class, Integer.TYPE);
chmodMethod.setAccessible(true);
return (Integer)chmodMethod.invoke(null, filename, mode);
} catch (Throwable ex) {
return -1;
}
}

在 solaris/linux 下工作。

Apache ant chmod (不是很优雅,为了完整性而添加)与@msorsky 共享的信用

    Chmod chmod = new Chmod();
chmod.setProject(new Project());
FileSet mySet = new FileSet();
mySet.setDir(new File("/my/path"));
mySet.setIncludes("**");
chmod.addFileset(mySet);
chmod.setPerm("+w");
chmod.setType(new FileDirBoth());
chmod.execute();

在 Java6之前,在 Java 级别上不支持文件权限更新。您必须实现自己的本机方法或调用 Runtime.exec()来执行诸如 Chmod之类的 OS 级命令。

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

从 Java7开始,引入了 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);

此方法只能在 POSIX 文件系统上使用,这意味着您不能在 Windows 系统上调用它。

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

有一个非常类似于 UNIX chmod 的 Oracle 文档上的示例类,但是它可以使用 javase7 + 。

如果您想为创建的文件设置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);
}

只是为了更新这个答案,除非以后有人碰到这个问题,因为您可以使用 JDK6

File file = new File('/directory/to/file');
file.setWritable(boolean);
file.setReadable(boolean);
file.setExecutable(boolean);

您可以找到有关 Oracle 文件(Java 平台 SE7)的文档。请记住,这些命令只有在当前工作用户拥有该文件的所有权或对该文件的写访问权时才有效。我知道 OP 想要 chmod 类型访问,以进行更复杂的用户配置。这些将为所有用户设置全面的选项。

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;


public class FileAndDirectory1 {
public static void main(String[] args) {
        

File file = new File("fileTest1.txt");
System.out.println(file.getAbsoluteFile());
try {
//file.createNewFile();
if(!file.exists())
{
//PosixFilePermission is an enum class, PosixFilePermissions is a final class
                

//create file permissions from string
Set<PosixFilePermission> filePermissions = PosixFilePermissions.fromString("---------"/* "rwxrwxrwx" */);
FileAttribute<?> permissions = PosixFilePermissions.asFileAttribute(filePermissions);
Files.createFile(file.toPath(), permissions);
// printing the permissions associated with the file
System.out.println("Executable: " + file.canExecute());
System.out.println("Readable: " + file.canRead());
System.out.println("Writable: "+ file.canWrite());


file.setExecutable(true);
file.setReadable(true);
file.setWritable(true);
}
else
{
//modify permissions
                

//get the permission using file attributes
Set<PosixFilePermission> perms = Files.readAttributes(file.toPath(), PosixFileAttributes.class).permissions();
perms.remove(PosixFilePermission.OWNER_WRITE);


perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_EXECUTE);
perms.add(PosixFilePermission.GROUP_WRITE);
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.OTHERS_WRITE);
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OTHERS_EXECUTE);
Files.setPosixFilePermissions(file.toPath(), perms);


System.out.println("Executable: " + file.canExecute());
System.out.println("Readable: " + file.canRead());
System.out.println("Writable: "+ file.canWrite());


file.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
Path path = Paths.get(String.valueOf(file));
System.out.println(path);
}
}