2009-03-19 58 views
83

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 hiện tương đương Java của chmod. Đó có phải là Java 5 không? Nếu vậy, làm thế nào?Làm cách nào để thay đổi quyền truy cập tệp?

Tôi biết trong Java 6 đối tượng Tệp có phương thức setReadable()/setWritable(). 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ể.

Trả lời

75

Kiểm soát hoàn toàn thuộc tính tệp có sẵn trong Java 7, như một phần của cơ sở IO mới "mới" (NIO.2). Ví dụ: quyền POSIX có thể được đặt bằng setPosixFilePermissions().

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

+3

chọn này như tôi không có khả năng sử dụng câu trả lời của Marty Lamb. –

+1

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

+0

Vâng, đã lâu rồi. – erickson

39

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

Thông báo trước duy nhất là nó chậm hơn jni, vì vậy nếu bạn đang thực hiện việc này với số lượng tệp rất lớn có thể là vấn đề với bạn.

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

Dưới đây là một jna hoàn dụ 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); 
} 
+0

JNA là một công cụ tuyệt vời cho các cuộc gọi bản địa! – erickson

+2

Để xử lý lỗi chính xác, CLibrary.chmod() phải được khai báo để ném com.sun.jna.LastErrorException. Đó là cách duy nhất an toàn thread để nhận giá trị errno được thiết lập bởi lệnh chmod(). Nếu không, bạn có thể nhận trạng thái thành công/lỗi từ giá trị trả về, nhưng không thể nhận được mã lỗi thực tế. –

4

Bạn có thể sử dụng các phương pháp của lớp File: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

+3

Vui lòng xem lại câu hỏi thứ hai. Roy Rico biết về setReadable() và setWritable(), nhưng chúng chỉ cho phép bạn thay đổi quyền của chủ sở hữu, không phải quyền của nhóm hoặc mọi người hoặc bất kỳ cờ nào khác. – ChrisB

15

cho các cửa sổ 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

hoạt động tốt. Việc sửa đổi duy nhất được thực hiện 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 bạn đã nhập mã! –

+0

@bob .. bạn có thể cho tôi lớp AclFileAttributeView và UserPrincipalLookupService .. bcz nó không thể giải quyết .. bạn trả lời có vẻ là làm việc .. và tôi muốn thực hiện –

+0

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

4

for 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; 
    } 
} 

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

+0

người ta phải biết rằng 'FileSystemPreferences' spwans một chủ đề daemon' Timer' một khi nó được nạp. nó cũng thêm một cái móc tắt máy, nhưng đối với một số ứng dụng, điều này vẫn có thể có vấn đề. – thrau

2

Apache kiến ​​chmod (không phải là rất tao nhã, thêm nó cho đầy đủ) tín dụng 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(); 
3

Ngoài câu trả lời Erickson ở đây một liên kết hữu ích với các ví dụ mã làm việc về việc sử dụng PosixFilePermissions:

http://www.journaldev.com/855/how-to-set-file-permissions-in-java-easily-using-java-7-posixfilepermission

+0

Trong khi điều này về mặt lý thuyết có thể trả lời câu hỏi, [nó sẽ là thích hợp hơn] (// meta.stackoverflow.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. –

15

Trước Java 6, không có hỗ trợ cập nhật quyền tệp ở cấp Java. Bạn phải triển khai phương thức gốc của riêng mình hoặc gọi Runtime.exec() để thực thi lệnh mức hệ điều hành 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 đối với tệp. Nhưng nó không mô phỏng hệ thống tệp POSIX cho phép thiết lập quyền cho người dùng khác nhau. File.setXXX() chỉ cho phép thiết lập quyền cho chủ sở hữu và mọi người khác.

Bắt đầu từ Java 7, quyền 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 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ý quyền của tệp, khuyên bạn nên đọc this post.

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: how to change file permission in java

5

Nếu bạn muốn thiết lập 777 phép tập tin được tạo của bạn hơn bạn có thể sử dụng phương pháp sau đây:

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

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

    Files.setPosixFilePermissions(file.toPath(), perms); 
} 
Các vấn đề liên quan