Bagaimana cara mengubah izin file secara terprogram?

115

Di Java, saya secara dinamis membuat satu set file dan saya ingin mengubah izin file pada file ini di sistem file linux / unix. Saya ingin dapat menjalankan persamaan Java dengan chmod. Apakah itu mungkin Java 5? Jika ya, bagaimana caranya?

Saya tahu di Java 6 Fileobjek memiliki setReadable()/ setWritable()metode. Saya juga tahu bahwa saya dapat melakukan panggilan sistem untuk melakukan ini, tetapi saya ingin menghindarinya jika memungkinkan.

Roy Rico
sumber
2
Catatan untuk yang lain: Untuk file yang sudah ada, sejak Java 7, Anda dapat menggunakan satu baris ini:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Jawaban:

110

Kontrol penuh atas atribut file tersedia di Java 7, sebagai bagian dari fasilitas "baru" IO Baru ( NIO.2 ). Misalnya, izin POSIX dapat diatur pada file yang ada dengan setPosixFilePermissions(), atau secara atomis pada pembuatan file dengan metode seperti createFile()atau newByteChannel().

Anda dapat membuat satu set izin menggunakan EnumSet.of(), tetapi metode helper PosixFilePermissions.fromString()akan menggunakan format konvensional yang akan lebih mudah dibaca oleh banyak pengembang. Untuk API yang menerima FileAttribute, Anda bisa menggabungkan set izin dengan PosixFilePermissions.asFileAttribute().

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

Di versi Java sebelumnya, menggunakan kode asli Anda sendiri, atau executilitas baris perintah -ing adalah pendekatan yang umum.

erickson
sumber
4
memilih yang ini karena saya tidak memiliki kemampuan untuk menggunakan jawaban Marty Lamb.
Roy Rico
1
Saya benar-benar tidak percaya bahwa sudah lebih dari enam tahun sejak mereka mulai mengerjakan NIO.2 dan masih belum ada dalam JRE pengiriman.
Clee
8
Contoh kode mungkin berguna dalam jawaban Anda.
Ricardo Gladwell
2
Jawaban stackoverflow.com/a/32331442/290182 oleh @PixelsTech ini lebih unggul karena menyediakan kode contoh
beldaz
1
@Steam Semua siap.
erickson
43

Selain saran erickson, ada juga jna , yang memungkinkan Anda memanggil perpustakaan asli tanpa menggunakan jni. Ini sangat mudah digunakan, dan saya telah menggunakannya pada beberapa proyek dengan kesuksesan besar.

Satu-satunya peringatan adalah bahwa ini lebih lambat dari jni, jadi jika Anda melakukan ini pada sejumlah besar file yang mungkin menjadi masalah bagi Anda.

(Mengedit untuk menambahkan contoh)

Berikut contoh lengkap 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);
}
Marty Lamb
sumber
1
JNA adalah alat yang bagus untuk panggilan asli!
erickson
3
Untuk penanganan error yang benar, CLibrary.chmod () harus dideklarasikan untuk membuang com.sun.jna.LastErrorException. Itu adalah satu-satunya cara aman untuk mendapatkan nilai errno yang disetel oleh panggilan chmod (). Jika tidak, Anda bisa mendapatkan status berhasil / gagal dari nilai kembali, tetapi bukan kode kesalahan yang sebenarnya.
Simon Kissane
30

Sebelum Java 6, tidak ada dukungan pembaruan izin file di tingkat Java. Anda harus menerapkan metode asli Anda sendiri atau panggilan Runtime.exec()untuk menjalankan perintah tingkat OS seperti chmod .

Mulai dari Java 6, Anda dapat menggunakan File.setReadable()/File.setWritable()/File.setExecutable()untuk mengatur hak akses file. Tetapi itu tidak mensimulasikan sistem file POSIX yang memungkinkan untuk mengatur izin untuk pengguna yang berbeda. File.setXXX () hanya mengizinkan untuk mengatur izin untuk pemilik dan orang lain.

Mulai dari Java 7, izin file POSIX diperkenalkan. Anda dapat mengatur hak akses file seperti yang telah Anda lakukan pada sistem * nix. Sintaksnya adalah:

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

Metode ini hanya dapat digunakan pada sistem file POSIX, ini berarti Anda tidak dapat memanggilnya di sistem Windows.

Untuk detail tentang manajemen izin file, rekomendasikan Anda untuk membaca posting ini .

PixelsTech
sumber
18

untuk windows 7 dengan 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()));
}
bob
sumber
1
ini bekerja dengan baik. Modifikasi hanya dilakukan untuk metode lookupPrincipalByName (), saya mengirim System.getProperty ("user.name") bukan "user". Akhirnya tampak seperti upls.lookupPrincipalByName (System.getProperty ("user.name")); Terima kasih untuk kodenya!
isuru chathuranga
@ob .. dapatkah Anda memberi saya kelas AclFileAttributeView dan UserPrincipalLookupService .. bcz tidak dapat menyelesaikannya .. jawaban Anda tampaknya berfungsi .. dan saya ingin mengimplementasikan
Sagar Chavada
java.nio.file.attribute.AclFileAttributeView dan java.nio.file.attribute.UserPrincipalLookupService, memerlukan jdk 1.7+ untuk mengompilasi dan menjalankan.
bob
11

Jika Anda ingin mengatur 777 izin ke file yang Anda buat daripada Anda dapat menggunakan metode berikut:

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);
}
Apoorv Chourasiya
sumber
10

Hanya untuk memperbarui jawaban ini kecuali ada yang menemukan ini nanti, karena JDK 6 dapat Anda gunakan

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

Anda dapat menemukan dokumentasinya di File Oracle (Java Platform SE 7) . Ingatlah bahwa perintah ini hanya berfungsi jika pengguna yang bekerja saat ini memiliki kepemilikan atau akses tulis ke file itu. Saya sadar bahwa OP menginginkan akses tipe chmod untuk konfigurasi pengguna yang lebih rumit. ini akan menetapkan opsi di seluruh papan untuk semua pengguna.

TravisF
sumber
Keren, le sauveur!
khawarizmi
Saya telah mengujinya dengan Openjdk 11.0.6 di bawah Debian, berhasil!
Hartmut Schorrig
4

Anda dapat menggunakan metode kelas File: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

Erel Segal-Halevi
sumber
3
Silakan lihat kedua pertanyaan itu. Roy Rico tahu tentang setReadable () dan setWritable (), tetapi mereka hanya mengizinkan Anda mengubah izin pemilik, bukan izin grup atau semua orang, atau tanda lainnya.
ChrisB
3

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

bekerja di bawah solaris / linux.

Vlad
sumber
orang harus menyadari bahwa FileSystemPreferencesspwans Timerthread daemon setelah dimuat. itu juga menambahkan hook shutdown, tetapi untuk beberapa aplikasi ini mungkin masih bermasalah.
thrau
2

Apache ant chmod (tidak terlalu elegan, menambahkannya untuk kelengkapan) kredit yang dibagikan dengan @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();
ihadanny
sumber
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();
        }     

Referensi: cara mengubah izin file di java

Anuj Dhiman
sumber
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);
    }
}
Uddhav Gautam
sumber