Làm cách nào để tôi thay đổi quyền truy cập tệp?


115

Trong Java, tôi đang tự động tạo một tập hợp các tệp và tôi muốn thay đổi quyền của tệp trên các tệp này trên hệ thống tệp linux / unix. Tôi muốn có thể thực thi tương đương Java chmod. Java 5 có khả thi không? Nếu vậy thì thế nào?

Tôi biết trong Java 6 Fileđối tượng có setReadable()/ setWritable()phương thức. Tôi cũng biết tôi có thể thực hiện một cuộc gọi hệ thống để làm điều này, nhưng tôi muốn tránh điều đó nếu có thể.


2
Lưu ý cho những người khác: Đối với các tệp hiện có, kể từ Java 7, bạn có thể sử dụng lớp lót này:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Câu trả lời:


110

Toàn quyền kiểm soát các thuộc tính tệp có sẵn trong Java 7, như là một phần của cơ sở IO mới "mới" ( NIO.2 ). Ví dụ: quyền POSIX có thể được đặt trên một tệp hiện có setPosixFilePermissions(), hoặc nguyên tử khi tạo tệp với các phương thức như createFile()hoặc newByteChannel().

Bạn có thể tạo một tập các quyền bằng cách sử dụng EnumSet.of(), nhưng phương thức của trình trợ giúp PosixFilePermissions.fromString()sẽ sử dụng định dạng thông thường sẽ dễ đọc hơn đối với nhiều nhà phát triển. Đối với các API chấp nhận a FileAttribute, bạn có thể gói bộ quyền với PosixFilePermissions.asFileAttribute().

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

Trong các phiên bản trước của Java, sử dụng mã gốc của execcác tiện ích dòng lệnh hoặc -ing của riêng bạn là các cách tiếp cận phổ biến.


4
chọn cái này vì tôi không có khả năng sử dụng câu trả lời của Marty Lamb.
Roy Rico

1
Tôi thực sự không thể tin rằng đã hơn sáu năm kể từ khi họ bắt đầu làm việc trên NIO.2 và nó vẫn không nằm trong JRE vận chuyển.
clee

8
Mã ví dụ có thể hữu ích trong câu trả lời của bạn.
Ricardo Gladwell

2
Câu trả lời này stackoverflow.com/a/32331442/290182 bởi @PixelsTech là vượt trội vì nó cung cấp mã ví dụ
beldaz

1
@SteveB Tất cả các thiết lập.
erickson

43

Ngoài các đề xuất của erickson, còn có jna , cho phép bạn gọi các thư viện riêng mà không cần sử dụng jni. Nó cực kỳ dễ sử dụng và tôi đã sử dụng nó trong một vài dự án với thành công lớn.

Nhắc nhở duy nhất là nó chậm hơn jni, vì vậy nếu bạn đang làm điều này với một số lượng rất lớn các tệp có thể là một vấn đề cho bạn.

(Chỉnh sửa để thêm ví dụ)

Đây là một ví dụ jna chmod hoàn chỉnh:

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 là một công cụ tuyệt vời cho các cuộc gọi bản địa!
erickson

3
Để xử lý lỗi chính xác, CL Library.chmod () phải được khai báo để ném com.sun.jna.LastErrorException. Đó là cách duy nhất để đảm bảo giá trị errno được đặt bởi lệnh gọi chmod (). Mặt khác, bạn có thể nhận trạng thái thành công / thất bại từ giá trị trả về, nhưng không phải là mã lỗi thực tế.
Simon Kissane

30

Trước Java 6, không có hỗ trợ cập nhật quyền truy cập tệp ở cấp Java. Bạn phải thực hiện phương thức riêng của mình hoặc gọi Runtime.exec()để thực thi lệnh cấp OS, chẳng hạn như chmod .

Bắt đầu từ Java 6, bạn có thể sử dụng File.setReadable()/File.setWritable()/File.setExecutable()để đặt quyền truy cập tệp. Nhưng nó không mô phỏng hệ thống tệp POSIX cho phép đặt quyền cho những người dùng khác nhau. File.setXXX () chỉ cho phép đặt quyền cho chủ sở hữu và mọi người khác.

Bắt đầu từ Java 7, quyền truy cập tệp POSIX được giới thiệu. Bạn có thể đặt quyền truy cập tệp như những gì bạn đã thực hiện trên các hệ thống * nix. Cú pháp là:

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

Phương pháp này chỉ có thể được sử dụng trên hệ thống tệp POSIX, điều này có nghĩa là bạn không thể gọi nó trên hệ thống Windows.

Để biết chi tiết về quản lý cấp phép tập tin, khuyên bạn nên đọc bài viết này .


18

cho windows 7 với nio 2.0:

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
công việc này thật tuyệt Việc sửa đổi duy nhất được thực hiện là cho phương thức lookupPrincipalByName (), tôi đã gửi System.getProperty ("user.name") thay vì "user". Cuối cùng, nó trông giống như upls.lookupPrincipalByName (System.getProperty ("user.name")); Cảm ơn mã!
isuru chathuranga

@bob .. bạn có thể cho tôi lớp AclFileAttributionView và UserPrincipalLookupService .. bcz nó không thể giải quyết .. bạn trả lời dường như đang hoạt động .. và tôi muốn thực hiện
Sagar Chavada

java.nio.file.attribution.AclFileAttributionView và java.nio.file.attribution.UserPrincipalLookupService, nó yêu cầu jdk 1.7+ để biên dịch và chạy.
bob

10

Nếu bạn muốn đặt quyền 777 cho tệp đã tạo của mình, bạn có thể sử dụng phương pháp sau:

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

Chỉ cần cập nhật câu trả lời này trừ khi có ai gặp phải điều này sau, vì JDK 6 bạn có thể sử dụng

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

bạn có thể tìm thấy tài liệu trên Tệp Oracle (Nền tảng Java SE 7) . Hãy nhớ rằng các lệnh này chỉ hoạt động nếu người dùng đang làm việc hiện có quyền truy cập hoặc ghi quyền truy cập vào tệp đó. Tôi biết rằng OP muốn truy cập loại chmod cho cấu hình người dùng phức tạp hơn. những thứ này sẽ đặt tùy chọn trên bảng cho tất cả người dùng.


Thật tuyệt, le sauveur!
khawarizmi

Tôi đã thử nghiệm nó với Openjdk 11.0.6 trong Debian, nó hoạt động!
Hartmut Schorrig


3

cho Java 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;
    }
}

hoạt động dưới solaris / linux.


người ta nên biết rằng sẽ FileSystemPreferencestạo ra một Timerluồng daemon khi nó được tải. nó cũng thêm một móc tắt máy, nhưng đối với một số ứng dụng thì điều này vẫn có thể có vấn đề.
thrau

2

Tín dụng chmod của Apache (không thanh lịch, thêm vào để hoàn thiện) tín dụng được chia sẻ với @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();

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

Tham khảo: cách thay đổi quyền của tập tin trong java


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.