Come si modificano a livello di codice le autorizzazioni dei file?


115

In Java, sto creando dinamicamente un set di file e vorrei modificare i permessi dei file su questi file su un file system linux / unix. Mi piacerebbe essere in grado di eseguire l'equivalente Java di chmod. È possibile Java 5? Se é cosi, come?

So che in Java 6 l' Fileoggetto ha setReadable()/ setWritable()metodi. So anche che potrei fare una chiamata di sistema per farlo, ma vorrei evitarlo se possibile.


2
Nota per gli altri: per i file esistenti, a partire da Java 7, è possibile utilizzare questa riga:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Risposte:


110

Il controllo completo sugli attributi dei file è disponibile in Java 7, come parte della "nuova" funzione New IO ( NIO.2 ). Ad esempio, le autorizzazioni POSIX possono essere impostate su un file esistente con setPosixFilePermissions(), o atomicamente alla creazione del file con metodi come createFile()o newByteChannel().

Puoi creare una serie di autorizzazioni utilizzando EnumSet.of(), ma il metodo di supportoPosixFilePermissions.fromString() utilizzerà un formato convenzionale che sarà più leggibile per molti sviluppatori. Per le API che accettano un FileAttribute, puoi racchiudere il set di autorizzazioni con con PosixFilePermissions.asFileAttribute().

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

Nelle versioni precedenti di Java, utilizzando il proprio codice nativo o exec utilità della riga di comando -ing sono approcci comuni.


4
selezionando questo in quanto non ho la possibilità di utilizzare la risposta di Marty Lamb.
Roy Rico

1
Non riesco seriamente a credere che siano passati più di sei anni da quando hanno iniziato a lavorare su NIO.2 e non è ancora in un JRE di spedizione.
Clee

8
Un esempio di codice potrebbe essere utile nella tua risposta.
Ricardo Gladwell

2
Questa risposta stackoverflow.com/a/32331442/290182 da @PixelsTech è superiore in quanto fornisce codice di esempio
beldaz

1
@SteveB Tutto pronto.
erickson

43

Oltre ai suggerimenti di Erickson, c'è anche jna , che ti consente di chiamare le librerie native senza usare jni. È incredibilmente facile da usare e l'ho usato in un paio di progetti con grande successo.

L'unico avvertimento è che è più lento di jni, quindi se lo stai facendo su un numero molto elevato di file potrebbe essere un problema per te.

(Modifica per aggiungere un esempio)

Ecco un esempio completo di 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 è un ottimo strumento per le chiamate native!
erickson

3
Per una corretta gestione degli errori, è necessario dichiarare CLibrary.chmod () per generare com.sun.jna.LastErrorException. Questo è l'unico modo thread-safe per ottenere il valore errno impostato dalla chiamata chmod (). Altrimenti, puoi ottenere lo stato di successo / fallimento dal valore restituito, ma non dal codice di errore effettivo.
Simon Kissane

30

Prima di Java 6, non esisteva alcun supporto per l'aggiornamento dei permessi sui file a livello di Java. Devi implementare il tuo metodo nativo o chiamare Runtime.exec()per eseguire comandi a livello di sistema operativo come chmod .

A partire da Java 6, puoi usareFile.setReadable()/File.setWritable()/File.setExecutable() per impostare i permessi dei file. Ma non simula il file system POSIX che consente di impostare i permessi per diversi utenti. File.setXXX () consente solo di impostare l'autorizzazione per il proprietario e tutti gli altri.

A partire da Java 7, viene introdotto il permesso per i file POSIX. Puoi impostare i permessi dei file come quello che hai fatto sui sistemi * nix. La sintassi è:

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

Questo metodo può essere utilizzato solo sul file system POSIX, questo significa che non è possibile richiamarlo sul sistema Windows.

Per dettagli sulla gestione dei permessi sui file, ti consiglio di leggere questo post .


18

per windows 7 con 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
funziona alla grande. L'unica modifica apportata è stata per il metodo lookupPrincipalByName (), ho inviato System.getProperty ("user.name") invece di "user". Alla fine sembrava upls.lookupPrincipalByName (System.getProperty ("user.name")); Grazie per il codice!
isuru chathuranga

@bob .. puoi darmi la classe AclFileAttributeView e UserPrincipalLookupService .. bcz non può risolvere .. la tua risposta sembra funzionare .. e voglio implementare
Sagar Chavada

java.nio.file.attribute.AclFileAttributeView e java.nio.file.attribute.UserPrincipalLookupService, richiede jdk 1.7+ per essere compilato ed eseguito.
bob

11

Se desideri impostare l'autorizzazione 777 per il file creato, puoi utilizzare il seguente metodo:

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

Solo per aggiornare questa risposta a meno che qualcuno non lo trovi più tardi, poiché JDK 6 puoi usare

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

puoi trovare la documentazione su Oracle File (Java Platform SE 7) . Tieni presente che questi comandi funzionano solo se l'utente corrente ha la proprietà o l'accesso in scrittura a quel file. Sono consapevole del fatto che OP voleva l'accesso al tipo chmod per una configurazione utente più complessa. questi imposteranno l'opzione su tutta la linea per tutti gli utenti.


Fantastico, le sauveur!
khawarizmi

L'ho già testato con Openjdk 11.0.6 sotto Debian, funziona!
Hartmut Schorrig il


3

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

funziona sotto solaris / linux.


si dovrebbe essere consapevoli del fatto che si FileSystemPreferencesestende su un Timerthread daemon una volta caricato. aggiunge anche un hook di spegnimento, ma per alcune applicazioni questo potrebbe essere ancora problematico.
giovedì

2

Apache ant chmod (non molto elegante, aggiungendolo per completezza) credito condiviso con @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();
        }     

Riferimento: come modificare i permessi dei file in 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);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.