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


115

在Java中,我正在动态创建一组文件,并且想要更改linux / unix文件系统上这些文件的文件许可权。我希望能够执行的Java等效项chmod。那可能是Java 5吗?如果是这样,怎么办?

我知道在Java 6中File对象具有setReadable()/ setWritable()方法。我也知道我可以进行系统调用,但是如果可能的话,我想避免这种情况。


2
其他说明:对于现有文件,从Java 7开始,您可以使用以下一种格式:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Answers:


110

作为“新” New IO工具(NIO.2)的一部分,Java 7中提供了对文件属性的完全控制。例如,POSIX权限可以在与现有的文件设置setPosixFilePermissions()在文件创建与类似的方法或原子createFile()newByteChannel()

您可以使用来创建一组权限EnumSet.of(),但是helper方法PosixFilePermissions.fromString()将使用一种常规格式,该格式对于许多开发人员而言更易读。对于接受的API FileAttribute,您可以使用来包装权限集PosixFilePermissions.asFileAttribute()

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

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


4
选择此选项是因为我没有能力使用Marty Lamb的答案。
罗伊·里科

1
我真的不能相信,自从他们开始研究NIO.2至今已经有6年了,它仍然不在出货的JRE中。
clee 2010年

8
代码示例可能对您的答案很有用。
里卡多·格拉德威尔

2
@PixelsTech的这个答案stackoverflow.com/a/32331442/290182因为它提供了示例代码,所以效果更好
beldaz 2016年

1
@SteveB全部设置。
erickson

43

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

1
JNA是用于本地调用的好工具!
埃里克森

3
为了正确处理错误,必须声明CLibrary.chmod()引发com.sun.jna.LastErrorException。这是获取chmod()调用设置的errno值的唯一线程安全方法。否则,您可以从返回值(而不是实际的错误代码)中获取成功/失败状态。
西蒙·基桑

30

在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);

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

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


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()));
}

1
这很好。所做的唯一修改是针对lookupPrincipalByName()方法,我发送了System.getProperty(“ user.name”)而不是“ user”。最终看起来像upls.lookupPrincipalByName(System.getProperty(“ user.name”)));。感谢您的代码!
isuru chathuranga

@bob ..您能给我AclFileAttributeView和UserPrincipalLookupService类吗?bcz它无法解决..您的答案似乎正在起作用..我想实现
Sagar Chavada

java.nio.file.attribute.AclFileAttributeView和java.nio.file.attribute.UserPrincipalLookupService,它需要jdk 1.7+才能编译和运行。
鲍勃,2016年

11

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

10

只是为了更新此答案,除非以后有人遇到此问题,因为您可以使用JDK 6

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

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


酷,乐于助人!
khawarizmi

我已经在Debian下使用Openjdk 11.0.6对其进行了测试,它可以工作!
Hartmut Schorrig


3

对于Oralce Java 6:

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下工作。


应该注意的是,一旦加载守护进程线程,它就会FileSystemPreferences闪烁Timer。它还添加了一个关闭钩子,但是对于某些应用程序来说,这仍然是有问题的。
thrau

2

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

    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();

1
simple java code  for change file permission in java  

   String path="D:\\file\\read.txt";
        File file=new File(path);
        if (file.exists()) {
            System.out.println("read="+file.canRead());
            System.out.println("write="+file.canWrite());
            System.out.println("Execute="+file.canExecute());
            file.setReadOnly();
        }     

参考:如何在Java中更改文件权限



0
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);
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.