Wie ändere ich programmgesteuert Dateiberechtigungen?

115

In Java erstelle ich dynamisch eine Reihe von Dateien und möchte die Dateiberechtigungen für diese Dateien in einem Linux / Unix-Dateisystem ändern. Ich möchte in der Lage sein, das Java-Äquivalent von auszuführen chmod. Ist das möglich Java 5? Wenn das so ist, wie?

Ich weiß, dass das FileObjekt in Java 6 setReadable()/ setWritable()Methoden hat. Ich weiß auch, dass ich dazu einen Systemaufruf tätigen könnte, aber ich möchte dies nach Möglichkeit vermeiden.

Roy Rico
quelle
2
Hinweis für andere: Für vorhandene Dateien können Sie seit Java 7 diesen Einzeiler verwenden:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
Tom

Antworten:

110

Die vollständige Kontrolle über Dateiattribute ist in Java 7 als Teil der "neuen" neuen E / A-Funktion ( NIO.2 ) verfügbar . Zum Beispiel können POSIX - Berechtigungen auf eine Datei festgelegt werden mit setPosixFilePermissions(), oder atomar bei Dateierstellung mit Methoden wie createFile()oder newByteChannel().

Sie können eine Reihe von Berechtigungen mit erstellen EnumSet.of(), die Hilfsmethode PosixFilePermissions.fromString()verwendet jedoch ein herkömmliches Format, das für viele Entwickler besser lesbar ist. Für APIs, die a akzeptieren FileAttribute, können Sie den Berechtigungssatz mit umschließen PosixFilePermissions.asFileAttribute().

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

In früheren Versionen von Java sind die Verwendung von nativem Code oder execBefehlszeilenprogrammen von -ing gängige Ansätze.

erickson
quelle
4
Wählen Sie diese aus, da ich die Antwort von Marty Lamb nicht verwenden kann.
Roy Rico
1
Ich kann ernsthaft nicht glauben, dass es über sechs Jahre her ist, seit sie angefangen haben, an NIO.2 zu arbeiten, und es ist immer noch nicht in einer Versand-JRE.
Clee
8
Ein Codebeispiel kann in Ihrer Antwort hilfreich sein.
Ricardo Gladwell
2
Diese Antwort stackoverflow.com/a/32331442/290182 von @PixelsTech ist überlegen, da sie Beispielcode liefert
beldaz
1
@SteveB Alles klar.
Erickson
43

Zusätzlich zu den Vorschlägen von erickson gibt es auch jna , mit dem Sie native Bibliotheken aufrufen können, ohne jni zu verwenden. Es ist schockierend einfach zu bedienen und ich habe es bei einigen Projekten mit großem Erfolg eingesetzt.

Die einzige Einschränkung ist, dass es langsamer als jni ist. Wenn Sie dies also mit einer sehr großen Anzahl von Dateien tun, kann dies ein Problem für Sie sein.

(Bearbeiten, um ein Beispiel hinzuzufügen)

Hier ist ein vollständiges Beispiel für 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
quelle
1
JNA ist so ein nettes Tool für native Anrufe!
Erickson
3
Für eine korrekte Fehlerbehandlung muss CLibrary.chmod () deklariert werden, um eine com.sun.jna.LastErrorException auszulösen. Dies ist die einzige thread-sichere Methode, um den durch den Aufruf von chmod () festgelegten errno-Wert abzurufen. Andernfalls können Sie den Erfolgs- / Fehlerstatus aus dem Rückgabewert abrufen, nicht jedoch aus dem tatsächlichen Fehlercode.
Simon Kissane
30

Vor Java 6 wird die Aktualisierung von Dateiberechtigungen auf Java-Ebene nicht unterstützt. Sie müssen Ihre eigene native Methode oder Ihren eigenen Aufruf implementieren Runtime.exec(), um Befehle auf Betriebssystemebene wie chmod auszuführen .

Ab Java 6 können Sie File.setReadable()/File.setWritable()/File.setExecutable()Dateiberechtigungen festlegen. Das POSIX-Dateisystem, mit dem Berechtigungen für verschiedene Benutzer festgelegt werden können, wird jedoch nicht simuliert. Mit File.setXXX () können nur Berechtigungen für den Eigentümer und alle anderen festgelegt werden.

Ab Java 7 wird die POSIX-Dateiberechtigung eingeführt. Sie können Dateiberechtigungen festlegen, wie Sie sie auf * nix-Systemen ausgeführt haben. Die Syntax lautet:

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

Diese Methode kann nur im POSIX-Dateisystem verwendet werden. Dies bedeutet, dass Sie sie nicht im Windows-System aufrufen können.

Für Details zur Verwaltung von Dateiberechtigungen empfehlen wir Ihnen, diesen Beitrag zu lesen .

PixelsTech
quelle
18

für Windows 7 mit 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
quelle
1
das funktioniert super. Die einzige vorgenommene Änderung betraf die Methode lookupPrincipalByName (). Ich habe System.getProperty ("user.name") anstelle von "user" gesendet. Schließlich sah es aus wie upls.lookupPrincipalByName (System.getProperty ("user.name")); Danke für den Code!
Isuru Chathuranga
@ Bob .. können Sie mir AclFileAttributeView und UserPrincipalLookupService Klasse geben .. bcz es kann nicht aufgelöst werden .. Sie antworten scheint zu funktionieren .. und ich möchte implementieren
Sagar Chavada
Für java.nio.file.attribute.AclFileAttributeView und java.nio.file.attribute.UserPrincipalLookupService ist jdk 1.7+ erforderlich, um kompiliert und ausgeführt zu werden.
Bob
10

Wenn Sie die 777-Berechtigung für Ihre erstellte Datei festlegen möchten, können Sie die folgende Methode verwenden:

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
quelle
10

Nur um diese Antwort zu aktualisieren, es sei denn, jemand stößt später darauf, da Sie JDK 6 verwenden können

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

Sie finden die Dokumentation zu Oracle File (Java Platform SE 7) . Beachten Sie, dass diese Befehle nur funktionieren, wenn der aktuell arbeitende Benutzer Eigentümer oder Schreibzugriff auf diese Datei ist. Mir ist bekannt, dass OP einen Zugriff vom Typ chmod für eine komplexere Benutzerkonfiguration wünschte. Dadurch wird die Option für alle Benutzer allgemein festgelegt.

TravisF
quelle
Cool, le sauveur!
Khawarizmi
Ich habe es noch mit Openjdk 11.0.6 unter Debian getestet, es funktioniert!
Hartmut Schorrig
4

Sie können die Methoden der File-Klasse verwenden: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

Erel Segal-Halevi
quelle
3
Bitte werfen Sie einen zweiten Blick auf die Frage. Roy Rico kennt setReadable () und setWritable (), aber Sie können nur die Eigentümerberechtigungen ändern, nicht die Gruppen- oder Einzelberechtigungen oder eines der anderen Flags.
ChrisB
3

für 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;
    }
}

funktioniert unter solaris / linux.

Vlad
quelle
Man sollte sich bewusst sein, dass FileSystemPreferencesein TimerDaemon-Thread nach dem Laden spwans . Es wird auch ein Shutdown-Hook hinzugefügt, aber für einige Anwendungen kann dies immer noch problematisch sein.
thrau
2

Apache ant chmod (nicht sehr elegant, der Vollständigkeit halber hinzugefügt) Kredit mit @msorsky geteilt

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

Referenz: So ändern Sie die Dateiberechtigung in Java

Anuj Dhiman
quelle