Dosya izinlerini programlı olarak nasıl değiştiririm?


115

Java'da dinamik olarak bir dizi dosya oluşturuyorum ve bir linux / unix dosya sisteminde bu dosyalardaki dosya izinlerini değiştirmek istiyorum. Java'nın eşdeğerini çalıştırabilmek istiyorum chmod. Bu mümkün Java 5 mi? Öyleyse nasıl?

Java 6'da Filenesnenin setReadable()/ setWritable()yöntemler olduğunu biliyorum . Bunu yapmak için bir sistem çağrısı yapabileceğimi de biliyorum, ancak mümkünse bundan kaçınmak isterim.


2
Diğerleri için not: Var olan dosyalar için, Java 7'den beri, şu tek Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Yanıtlar:


110

Dosya öznitelikleri üzerinde tam denetim, "yeni" Yeni GÇ tesisinin ( NIO.2 ) bir parçası olarak Java 7'de mevcuttur . Örneğin, POSIX izinleri ile varolan dosya üzerinde ayarlanabilir setPosixFilePermissions(), gibi yöntemlerle dosya oluşturma sırasında atomik veya createFile()ya newByteChannel().

Kullanarak bir dizi izin oluşturabilirsiniz EnumSet.of(), ancak yardımcı yöntem PosixFilePermissions.fromString(), birçok geliştirici tarafından daha okunabilir olacak geleneksel bir biçim kullanır. A kabul eden API'ler için FileAttributeizin kümesini ile kaydırabilirsiniz PosixFilePermissions.asFileAttribute().

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

Java'nın önceki sürümlerinde, kendi yerel kodunu veya exec-ing komut satırı yardımcı programlarını kullanmak yaygın yaklaşımlardır.


4
Marty Lamb'in cevabını kullanma yeteneğim olmadığı için bunu seçiyorum.
Roy Rico

1
NIO.2 üzerinde çalışmaya başladıklarından bu yana altı yıldan fazla zaman geçtiğine ve hala bir nakliye JRE'sinde bulunmadığına ciddi olarak inanamıyorum.
clee

8
Cevabınızda kod örneği faydalı olabilir.
Ricardo Gladwell

2
@PixelsTech'in bu yanıtı stackoverflow.com/a/32331442/290182 , örnek kod sağladığı için üstündür
beldaz

1
@SteveB Her şey hazır.
erickson

43

Ericson'ın önerilerine ek olarak, jni kullanmadan yerel kütüphaneleri çağırmanıza izin veren jna da var . Kullanımı şaşırtıcı derecede kolay ve bunu birkaç projede büyük başarı ile kullandım.

Tek uyarı, jni'den daha yavaş olmasıdır, bu nedenle, bunu sizin için bir sorun olabilecek çok sayıda dosyaya yapıyorsanız.

(Örnek eklemek için düzenleme)

İşte eksiksiz bir jna chmod örneği:

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, yerel aramalar için çok güzel bir araçtır!
erickson

3
Doğru hata işleme için, CLibrary.chmod () com.sun.jna.LastErrorException atacak şekilde bildirilmelidir. Bu, chmod () çağrısı tarafından ayarlanan errno değerini elde etmenin tek iş parçacığı güvenli yoludur. Aksi takdirde, başarı / başarısızlık durumunu dönüş değerinden alabilirsiniz, ancak gerçek hata kodunu alamazsınız.
Simon Kissane

30

Java 6'dan önce, Java düzeyinde dosya izni güncelleme desteği yoktur. Kendi yerel yönteminizi uygulamanız veya chmodRuntime.exec() gibi işletim sistemi düzeyinde komutu yürütmek için çağrı yapmanız gerekir .

Java 6'dan başlayarak, File.setReadable()/File.setWritable()/File.setExecutable()dosya izinlerini ayarlamak için kullanabilirsiniz . Ancak, farklı kullanıcılar için izin ayarlamaya izin veren POSIX dosya sistemini simüle etmez. File.setXXX () yalnızca sahip ve diğer herkes için izin ayarlamaya izin verir.

Java 7'den başlayarak, POSIX dosya izni tanıtıldı. * Nix sistemlerinde yaptığınız gibi dosya izinlerini ayarlayabilirsiniz. Sözdizimi şöyledir:

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

Bu yöntem yalnızca POSIX dosya sisteminde kullanılabilir, bu, onu Windows sisteminde çağıramayacağınız anlamına gelir.

Dosya izin yönetimi ile ilgili ayrıntılar için bu yazıyı okumanızı tavsiye ederiz. .


18

nio 2.0 ile Windows 7 için:

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
bu harika çalışıyor. Tek değişiklik lookupPrincipalByName () yöntemi içindi, "user" yerine System.getProperty ("user.name") gönderdim. Son olarak upls.lookupPrincipalByName (System.getProperty ("user.name")); Kod için teşekkürler!
isuru chathuranga

@bob .. bana AclFileAttributeView ve UserPrincipalLookupService sınıfını verebilir misin .. bcz çözemiyor .. cevabın çalışıyor gibi görünüyor .. ve uygulamak istiyorum
Sagar Chavada

java.nio.file.attribute.AclFileAttributeView ve java.nio.file.attribute.UserPrincipalLookupService, derlemek ve çalıştırmak için jdk 1.7+ gerektirir.
bob

11

Oluşturulan dosyanıza 777 iznini ayarlamak istiyorsanız, aşağıdaki yöntemi kullanabilirsiniz:

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

Sadece bu yanıtı güncellemek için, daha sonra kimse gelmezse, JDK 6'dan

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

belgeleri Oracle File'da (Java Platform SE 7) bulabilirsiniz . Bu komutların yalnızca geçerli çalışan kullanıcının bu dosyaya sahiplik veya yazma erişimi varsa çalıştığını unutmayın. OP'nin daha karmaşık kullanıcı yapılandırması için chmod türü erişim istediğinin farkındayım. bunlar seçeneği tüm kullanıcılar için panoda belirleyecektir.


Harika, le sauveur!
khawarizmi

Debian altında Openjdk 11.0.6 ile henüz test ettim, çalışıyor!
Hartmut Schorrig


3

Oralce Java 6 için:

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 altında çalışır.


yüklendikten sonra FileSystemPreferencesbir Timerdaemon iş parçacığı yaydığının bilinmesi gerekir . aynı zamanda bir kapatma kancası ekler, ancak bazı uygulamalar için bu yine de sorunlu olabilir.
2016 12

2

@Msorsky ile paylaşılan Apache ant chmod (çok zarif değil, bütünlük için ekleyerek) kredi

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

Referans: Java'da dosya izni nasıl değiştirilir



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);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.