Jak programowo zmienić uprawnienia do plików?


115

W Javie dynamicznie tworzę zestaw plików i chciałbym zmienić uprawnienia do tych plików w systemie plików linux / unix. Chciałbym móc wykonać odpowiednik Java chmod. Czy to możliwe Java 5? Jeśli tak to jak?

Wiem, że w Javie 6 Fileobiekt ma setReadable()/ setWritable()metody. Wiem również, że mógłbym wykonać wywołanie systemowe, aby to zrobić, ale chciałbym tego uniknąć, jeśli to możliwe.


2
Uwaga dla innych: Dla istniejących plików, ponieważ Java 7, można użyć tego jednego-liner:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Odpowiedzi:


110

Pełna kontrola nad atrybutami plików jest dostępna w Javie 7, jako część „nowego” narzędzia New IO ( NIO.2 ). Na przykład, uprawnienia POSIX można ustawić na istniejącym pliku setPosixFilePermissions(), lub atomowo na tworzenie plików z metod, takich jak createFile()czy newByteChannel().

Możesz utworzyć zestaw uprawnień za pomocą EnumSet.of(), ale metoda pomocnicza PosixFilePermissions.fromString()użyje konwencjonalnego formatu, który będzie bardziej czytelny dla wielu programistów. W przypadku interfejsów API, które akceptują a FileAttribute, możesz opakować zestaw uprawnień za pomocą PosixFilePermissions.asFileAttribute().

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

We wcześniejszych wersjach języka Java używanie własnego kodu natywnego lub execnarzędzi wiersza poleceń jest powszechnym podejściem.


4
wybierając ten, ponieważ nie mam możliwości wykorzystania odpowiedzi Marty Lamb.
Roy Rico,

1
Naprawdę nie mogę uwierzyć, że minęło ponad sześć lat, odkąd zaczęli pracować nad NIO.2, a nadal nie ma go w wysyłanym JRE.
clee

8
Przykładowy kod może być przydatny w Twojej odpowiedzi.
Ricardo Gladwell,

2
Ta odpowiedź stackoverflow.com/a/32331442/290182 autorstwa @PixelsTech jest lepsza, ponieważ zawiera przykładowy kod
beldaz

1
@SteveB Wszystko gotowe.
erickson

43

Oprócz sugestii ericksona istnieje również jna , która pozwala na wywoływanie natywnych bibliotek bez używania jni. Jest szokująco łatwy w użyciu i użyłem go w kilku projektach z wielkim sukcesem.

Jedynym zastrzeżeniem jest to, że jest wolniejszy niż jni, więc jeśli robisz to z bardzo dużą liczbą plików, może to stanowić problem.

(Edycja w celu dodania przykładu)

Oto pełny przykład 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 to takie fajne narzędzie do rozmów rodzimych!
erickson

3
Aby zapewnić poprawną obsługę błędów, należy zadeklarować CLibrary.chmod (), aby zgłaszać com.sun.jna.LastErrorException. Jest to jedyny bezpieczny dla wątków sposób uzyskania wartości errno ustawionej przez wywołanie chmod (). W przeciwnym razie stan powodzenia / niepowodzenia można uzyskać na podstawie wartości zwracanej, ale nie z rzeczywistego kodu błędu.
Simon Kissane,

30

W wersjach starszych niż Java 6 nie ma obsługi aktualizacji uprawnień do plików na poziomie Java. Musisz zaimplementować własną natywną metodę lub wywołanie, Runtime.exec()aby wykonać polecenie na poziomie systemu operacyjnego, takie jak chmod .

Począwszy od Java 6, możesz użyć File.setReadable()/File.setWritable()/File.setExecutable()do ustawiania uprawnień do plików. Ale nie symuluje systemu plików POSIX, który pozwala na ustawienie uprawnień dla różnych użytkowników. File.setXXX () pozwala tylko na ustawienie uprawnień dla właściciela i wszystkich innych.

Począwszy od Java 7, wprowadzono uprawnienia do plików POSIX. Możesz ustawić uprawnienia do plików, tak jak to robiłeś w systemach * nix. Składnia jest następująca:

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

Tej metody można używać tylko w systemie plików POSIX, co oznacza, że ​​nie można jej wywołać w systemie Windows.

Aby uzyskać szczegółowe informacje na temat zarządzania uprawnieniami do plików, przeczytaj ten post .


18

dla Windows 7 z 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
to działa świetnie. Jedyną wprowadzoną modyfikacją była metoda lookupPrincipalByName (), wysłałem System.getProperty („user.name”) zamiast „user”. Wreszcie wyglądało to jak upls.lookupPrincipalByName (System.getProperty ("nazwa.użytkownika")); Dzięki za kod!
isuru chathuranga

@bob .. czy możesz mi podać klasy AclFileAttributeView i UserPrincipalLookupService .. bcz nie mogę rozwiązać .. Twoja odpowiedź wydaje się działać .. i chcę wdrożyć
Sagar Chavada

java.nio.file.attribute.AclFileAttributeView i java.nio.file.attribute.UserPrincipalLookupService, wymaga jdk 1.7+ do skompilowania i uruchomienia.
bob

11

Jeśli chcesz ustawić uprawnienia 777 do utworzonego pliku, możesz użyć następującej metody:

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

Po prostu zaktualizuj tę odpowiedź, chyba że ktoś napotka to później, ponieważ JDK 6 możesz użyć

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

dokumentację można znaleźć w Oracle File (Java Platform SE 7) . Należy pamiętać, że te polecenia działają tylko wtedy, gdy bieżący pracujący użytkownik ma prawo własności lub uprawnienia do zapisu w tym pliku. Zdaję sobie sprawę, że OP chciał dostępu typu chmod do bardziej skomplikowanej konfiguracji użytkownika. te ustawią tę opcję dla wszystkich użytkowników.


Cool, le sauveur!
khawarizmi

Testowałem to jeszcze z Openjdk 11.0.6 pod Debianem, działa!
Hartmut Schorrig


3

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

działa pod Solarisem / Linuksem.


należy pamiętać, że po załadowaniu FileSystemPreferencesspwansuje Timerwątek demona. dodaje również hak zamykający, ale w przypadku niektórych aplikacji może to nadal być problematyczne.
czwartek,

2

Apache ant chmod (niezbyt elegancki, dodając go dla kompletności) udostępniony @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();
        }     

Odniesienie: jak zmienić uprawnienia do pliku w java



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);
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.