ฉันจะเปลี่ยนสิทธิ์ของไฟล์โดยทางโปรแกรมได้อย่างไร


115

ใน Java ฉันกำลังสร้างชุดไฟล์แบบไดนามิกและฉันต้องการเปลี่ยนสิทธิ์ของไฟล์บนไฟล์เหล่านี้บนระบบไฟล์ linux / unix ฉันต้องการที่จะสามารถรัน Java ได้เทียบเท่ากับchmod. เป็นไปได้ว่า Java 5? ถ้าเป็นอย่างไร

ฉันรู้ใน Java 6 FileวัตถุมีsetReadable()/ setWritable()วิธีการ ฉันรู้ด้วยว่าฉันสามารถเรียกระบบให้ทำสิ่งนี้ได้ แต่ฉันต้องการหลีกเลี่ยงสิ่งนั้นถ้าเป็นไปได้


2
หมายเหตุสำหรับคนอื่น ๆ : สำหรับไฟล์ที่มีอยู่ตั้งแต่ Java 7 คุณสามารถใช้หนึ่งซับ:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
ทอม

คำตอบ:


110

การควบคุมแอ็ตทริบิวต์ไฟล์อย่างสมบูรณ์มีอยู่ใน Java 7 ซึ่งเป็นส่วนหนึ่งของสิ่งอำนวยความสะดวก IO ใหม่ "ใหม่" ( NIO.2 ) ยกตัวอย่างเช่น POSIX สิทธิ์ที่สามารถตั้งค่าในแฟ้มที่มีอยู่ด้วยsetPosixFilePermissions(),หรืออะตอมที่สร้างไฟล์ที่มีวิธีการเช่นหรือcreateFile()newByteChannel()

คุณสามารถสร้างชุดสิทธิ์โดยใช้EnumSet.of()แต่วิธีการช่วยเหลือPosixFilePermissions.fromString()จะใช้รูปแบบทั่วไปซึ่งนักพัฒนาหลายคนจะอ่านได้ง่ายขึ้น สำหรับ API ที่ยอมรับ a 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
Roy Rico

1
ฉันไม่อยากจะเชื่อเลยว่ามันเป็นเวลากว่าหกปีแล้วที่พวกเขาเริ่มทำงานกับ NIO.2 และมันก็ยังไม่ได้อยู่ในการจัดส่ง JRE
clee

8
ตัวอย่างโค้ดอาจมีประโยชน์ในคำตอบของคุณ
Ricardo Gladwell

2
คำตอบนี้stackoverflow.com/a/32331442/290182โดย @PixelsTech ดีกว่าเนื่องจากมีรหัสตัวอย่าง
beldaz

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 เป็นเครื่องมือที่ดีสำหรับการโทรแบบเนทีฟ!
erickson

3
สำหรับการจัดการข้อผิดพลาดที่ถูกต้อง CLibrary.chmod () ต้องถูกประกาศว่าจะ throw com.sun.jna.LastErrorException นั่นเป็นวิธีเดียวที่ปลอดภัยสำหรับเธรดในการรับค่า errno ที่กำหนดโดยการเรียก chmod () มิฉะนั้นคุณจะได้รับสถานะความสำเร็จ / ล้มเหลวจากค่าส่งคืน แต่ไม่ใช่รหัสข้อผิดพลาดจริง
Simon Kissane

30

ก่อน Java 6 ไม่มีการสนับสนุนการอัปเดตการอนุญาตไฟล์ที่ระดับ Java คุณจะต้องใช้วิธีการดั้งเดิมของคุณเองหรือโทรRuntime.exec()ดำเนินการคำสั่งระดับ OS เช่น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

สำหรับ windows 7 พร้อม 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
มันใช้งานได้ดี การแก้ไขเพียงอย่างเดียวคือสำหรับเมธอด lookupPrincipalByName () ฉันส่ง System.getProperty ("user.name") แทน "ผู้ใช้" ในที่สุดดูเหมือนว่า 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+ เพื่อคอมไพล์และรัน
บ็อบ

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

คุณสามารถค้นหาเอกสารเกี่ยวกับออราเคิลไฟล์ (Java Platform SE 7) โปรดทราบว่าคำสั่งเหล่านี้ใช้ได้เฉพาะเมื่อผู้ใช้ที่ทำงานปัจจุบันมีสิทธิ์เป็นเจ้าของหรือเขียนเข้าถึงไฟล์นั้น ฉันทราบว่า OP ต้องการการเข้าถึงประเภท chmod สำหรับการกำหนดค่าผู้ใช้ที่ซับซ้อนมากขึ้น สิ่งเหล่านี้จะตั้งค่าตัวเลือกทั่วทั้งกระดานสำหรับผู้ใช้ทั้งหมด


เด็ดเลอค่า!
khawarizmi

ฉันได้ทดสอบด้วย Openjdk 11.0.6 ภายใต้ Debian มันใช้งานได้!
Hartmut Schorrig

4

คุณสามารถใช้วิธีการของคลาสไฟล์: http://docs.oracle.com/javase/7/docs/api/java/io/File.html


3
โปรดดูคำถามอีกครั้ง Roy Rico รู้เกี่ยวกับ setReadable () และ setWritable () แต่อนุญาตให้คุณเปลี่ยนสิทธิ์ของเจ้าของเท่านั้นไม่ใช่สิทธิ์ของกลุ่มหรือทุกคนหรือแฟล็กอื่น ๆ
ChrisB

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


ควรทราบว่าFileSystemPreferencesspwans Timerdaemon thread เมื่อโหลดแล้ว นอกจากนี้ยังเพิ่ม hook การปิดระบบ แต่สำหรับบางแอปพลิเคชันอาจยังคงเป็นปัญหา
thrau

2

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



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);
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.