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.

Roy Rico
źródło
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.

erickson
źródło
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);
}
Marty Lamb
źródło
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 .

PixelsTech
źródło
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()));
}
pion
źródło
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);
}
Apoorv Chourasiya
źródło
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.

TravisF
źródło
Cool, le sauveur!
khawarizmi
Testowałem to jeszcze z Openjdk 11.0.6 pod Debianem, działa!
Hartmut Schorrig
4

Możesz użyć metod klasy File: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

Erel Segal-Halevi
źródło
3
Proszę spojrzeć ponownie na pytanie. Roy Rico wie o setReadable () i setWritable (), ale pozwalają one tylko na zmianę uprawnień właściciela, a nie uprawnień grupy lub wszystkich, ani innych flag.
ChrisB,
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.

Vlad
źródło
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();
ihadanny
źródło
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

Anuj Dhiman
źródło
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
źródło