Comment modifier par programme les autorisations de fichier?

115

En Java, je crée dynamiquement un ensemble de fichiers et j'aimerais modifier les autorisations de fichiers sur ces fichiers sur un système de fichiers linux / unix. J'aimerais pouvoir exécuter l'équivalent Java de chmod. Est-ce possible Java 5? Si c'est le cas, comment?

Je sais que dans Java 6 l' Fileobjet a setReadable()/ setWritable()methods. Je sais aussi que je pourrais faire un appel système pour ce faire, mais j'aimerais éviter cela si possible.

Roy Rico
la source
2
Note pour les autres: Pour les fichiers existants, depuis Java 7, vous pouvez utiliser ce one-liner:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Réponses:

110

Le contrôle total des attributs de fichier est disponible dans Java 7, dans le cadre de la «nouvelle» fonction New IO ( NIO.2 ). Par exemple, les permissions POSIX peuvent être définies sur un fichier existant avec setPosixFilePermissions(), ou atomiquement lors de la création de fichiers avec des méthodes telles que createFile()ou newByteChannel().

Vous pouvez créer un ensemble d'autorisations à l'aide de EnumSet.of(), mais la méthode d'assistance PosixFilePermissions.fromString()utilisera un format conventionnel qui sera plus lisible pour de nombreux développeurs. Pour les API qui acceptent a FileAttribute, vous pouvez encapsuler l'ensemble d'autorisations avec avec PosixFilePermissions.asFileAttribute().

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

Dans les versions antérieures de Java, l'utilisation de votre propre code natif ou les executilitaires de ligne de commande -ing sont des approches courantes.

Erickson
la source
4
en sélectionnant celui-ci car je n'ai pas la possibilité d'utiliser la réponse de Marty Lamb.
Roy Rico
1
Je ne peux vraiment pas croire que cela fait plus de six ans qu'ils ont commencé à travailler sur NIO.2 et que ce n'est toujours pas dans un JRE d'expédition.
clee le
8
Un exemple de code peut être utile dans votre réponse.
Ricardo Gladwell le
2
Cette réponse stackoverflow.com/a/32331442/290182 par @PixelsTech est supérieure car elle fournit un exemple de code
beldaz
1
@SteveB Tout est prêt.
erickson
43

En plus des suggestions d'erickson, il y a aussi jna , qui vous permet d'appeler des bibliothèques natives sans utiliser jni. Il est incroyablement facile à utiliser et je l'ai utilisé sur quelques projets avec beaucoup de succès.

Le seul inconvénient est qu'il est plus lent que jni, donc si vous faites cela à un très grand nombre de fichiers, cela pourrait être un problème pour vous.

(Modification pour ajouter un exemple)

Voici un exemple complet de 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
la source
1
JNA est un si bel outil pour les appels natifs!
erickson
3
Pour une gestion correcte des erreurs, CLibrary.chmod () doit être déclaré pour lancer com.sun.jna.LastErrorException. C'est le seul moyen sûr pour les threads d'obtenir la valeur errno définie par l'appel chmod (). Sinon, vous pouvez obtenir l'état de réussite / échec à partir de la valeur de retour, mais pas du code d'erreur réel.
Simon Kissane
30

Avant Java 6, il n'y avait pas de prise en charge de la mise à jour des autorisations de fichiers au niveau Java. Vous devez implémenter votre propre méthode native ou appeler Runtime.exec()pour exécuter une commande au niveau du système d'exploitation telle que chmod .

À partir de Java 6, vous pouvez utiliser File.setReadable()/File.setWritable()/File.setExecutable()pour définir les autorisations de fichier. Mais il ne simule pas le système de fichiers POSIX qui permet de définir des autorisations pour différents utilisateurs. File.setXXX () permet uniquement de définir l'autorisation pour le propriétaire et tout le monde.

À partir de Java 7, l'autorisation de fichier POSIX est introduite. Vous pouvez définir des autorisations de fichiers comme ce que vous avez fait sur les systèmes * nix. La syntaxe est:

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

Cette méthode ne peut être utilisée que sur le système de fichiers POSIX, cela signifie que vous ne pouvez pas l'appeler sur le système Windows.

Pour plus de détails sur la gestion des autorisations de fichiers, nous vous recommandons de lire cet article .

PixelsTech
la source
18

pour Windows 7 avec 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
la source
1
cela fonctionne très bien. La seule modification effectuée concernait la méthode lookupPrincipalByName (), j'ai envoyé System.getProperty ("user.name") au lieu de "user". Enfin, cela ressemblait à upls.lookupPrincipalByName (System.getProperty ("user.name")); Merci pour le code!
isuru chathuranga
@bob .. pouvez-vous me donner la classe AclFileAttributeView et UserPrincipalLookupService .. bcz il ne peut pas résoudre .. votre réponse semble fonctionner .. et je veux mettre en œuvre
Sagar Chavada
java.nio.file.attribute.AclFileAttributeView et java.nio.file.attribute.UserPrincipalLookupService, il nécessite jdk 1.7+ pour être compilé et exécuté.
bob
11

Si vous souhaitez définir l'autorisation 777 sur votre fichier créé, vous pouvez utiliser la méthode suivante:

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
la source
10

Juste pour mettre à jour cette réponse à moins que quelqu'un ne rencontre cela plus tard, depuis JDK 6, vous pouvez utiliser

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

vous pouvez trouver la documentation sur Oracle File (Java Platform SE 7) . Gardez à l'esprit que ces commandes ne fonctionnent que si l'utilisateur actif actuel a la propriété ou un accès en écriture à ce fichier. Je suis conscient qu'OP voulait un accès de type chmod pour une configuration utilisateur plus complexe. ceux-ci définiront l'option à tous les niveaux pour tous les utilisateurs.

TravisF
la source
Cool, le sauveur!
khawarizmi
Je l'ai encore testé avec Openjdk 11.0.6 sous Debian, ça marche!
Hartmut Schorrig
4

Vous pouvez utiliser les méthodes de la classe File: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

Erel Segal-Halevi
la source
3
Veuillez jeter un second regard sur la question. Roy Rico connaît setReadable () et setWritable (), mais ils vous permettent uniquement de modifier les autorisations du propriétaire, pas les autorisations de groupe ou de tout le monde, ou l'un des autres indicateurs.
ChrisB
3

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

fonctionne sous solaris / linux.

Vlad
la source
il faut savoir que FileSystemPreferencesspwans un Timerthread démon une fois qu'il est chargé. il ajoute également un hook d'arrêt, mais pour certaines applications, cela peut encore être problématique.
thrau
2

Apache ant chmod (pas très élégant, en l'ajoutant pour être complet) crédit partagé avec @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
la source
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();
        }     

Référence: comment changer l'autorisation de fichier en java

Anuj Dhiman
la source
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
la source