¿Cómo cambio los permisos de archivo mediante programación?

115

En Java, estoy creando dinámicamente un conjunto de archivos y me gustaría cambiar los permisos de archivo en estos archivos en un sistema de archivos linux / unix. Me gustaría poder ejecutar el equivalente en Java de chmod. ¿Es eso posible Java 5? ¿Si es así, cómo?

Sé que en Java 6 el Fileobjeto tiene setReadable()/ setWritable()métodos. También sé que podría hacer una llamada al sistema para hacer esto, pero me gustaría evitarlo si es posible.

Roy Rico
fuente
2
Nota para los demás: para los archivos existentes, desde Java 7, puede utilizar este resumen:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
Tom

Respuestas:

110

El control total sobre los atributos del archivo está disponible en Java 7, como parte de la "nueva" función New IO ( NIO.2 ). Por ejemplo, los permisos POSIX se pueden establecer en un archivo existente con setPosixFilePermissions(), o de forma atómica en la creación del archivo con métodos como createFile()o newByteChannel().

Puede crear un conjunto de permisos utilizando EnumSet.of(), pero el método auxiliar PosixFilePermissions.fromString()utilizará un formato convencional que será más legible para muchos desarrolladores. Para las API que aceptan a FileAttribute, puede ajustar el conjunto de permisos con con PosixFilePermissions.asFileAttribute().

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

En versiones anteriores de Java, el uso de su propio código nativo o las executilidades de línea de comandos -ing son enfoques comunes.

erickson
fuente
4
seleccionando este porque no tengo la capacidad de usar la respuesta de Marty Lamb.
Roy Rico
1
En serio, no puedo creer que hayan pasado más de seis años desde que comenzaron a trabajar en NIO.2 y todavía no está en un JRE de envío.
clee
8
El ejemplo de código puede ser útil en su respuesta.
Ricardo Gladwell
2
Esta respuesta stackoverflow.com/a/32331442/290182 de @PixelsTech es superior ya que proporciona un código de ejemplo
beldaz
1
@SteveB Todo listo.
erickson
43

Además de las sugerencias de erickson, también existe jna , que le permite llamar a bibliotecas nativas sin usar jni. Es sorprendentemente fácil de usar y lo he usado en un par de proyectos con gran éxito.

La única advertencia es que es más lento que jni, por lo que si está haciendo esto con una gran cantidad de archivos, puede ser un problema para usted.

(Edición para agregar ejemplo)

Aquí hay un ejemplo completo 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
fuente
1
¡JNA es una buena herramienta para llamadas nativas!
erickson
3
Para un manejo correcto de errores, CLibrary.chmod () debe declararse para lanzar com.sun.jna.LastErrorException. Esa es la única forma segura para subprocesos de obtener el valor errno establecido por la llamada chmod (). De lo contrario, puede obtener el estado de éxito / error del valor de retorno, pero no del código de error real.
Simon Kissane
30

Antes de Java 6, no se admite la actualización de permisos de archivos a nivel de Java. Debe implementar su propio método nativo o llamar Runtime.exec()para ejecutar un comando de nivel de sistema operativo como chmod .

A partir de Java 6, puede utilizar File.setReadable()/File.setWritable()/File.setExecutable()para establecer permisos de archivo. Pero no simula el sistema de archivos POSIX que permite establecer permisos para diferentes usuarios. File.setXXX () solo permite establecer permisos para el propietario y todos los demás.

A partir de Java 7, se introduce el permiso de archivo POSIX. Puede establecer permisos de archivo como lo ha hecho en los sistemas * nix. La sintaxis es:

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

Este método solo se puede usar en el sistema de archivos POSIX, esto significa que no puede llamarlo en el sistema Windows.

Para obtener detalles sobre la administración de permisos de archivos, le recomendamos que lea esta publicación .

PixelsTech
fuente
18

para 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()));
}
Beto
fuente
1
esto funciona muy bien. La única modificación realizada fue para el método lookupPrincipalByName (), envié System.getProperty ("user.name") en lugar de "user". Finalmente, se veía como upls.lookupPrincipalByName (System.getProperty ("user.name")); ¡Gracias por el código!
isuru chathuranga
@bob ... ¿me pueden dar la clase AclFileAttributeView y UserPrincipalLookupService ... bcz no se puede resolver ... su respuesta parece estar funcionando ... y quiero implementar
Sagar Chavada
java.nio.file.attribute.AclFileAttributeView y java.nio.file.attribute.UserPrincipalLookupService, requiere jdk 1.7+ para compilar y ejecutar.
Bob
11

Si desea establecer el permiso 777 para su archivo creado, puede usar el siguiente método:

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

Solo para actualizar esta respuesta a menos que alguien se encuentre con esto más adelante, ya que JDK 6 puede usar

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

puede encontrar la documentación en Oracle File (Java Platform SE 7) . Tenga en cuenta que estos comandos solo funcionan si el usuario actual tiene la propiedad o acceso de escritura a ese archivo. Soy consciente de que OP quería acceso de tipo chmod para una configuración de usuario más compleja. estos establecerán la opción en todos los ámbitos para todos los usuarios.

TravisF
fuente
¡Genial, le sauveur!
khawarizmi
Ya lo he probado con Openjdk 11.0.6 en Debian, ¡funciona!
Hartmut Schorrig
4

Puede utilizar los métodos de la clase File: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

Erel Segal-Halevi
fuente
3
Por favor, eche un segundo vistazo a la pregunta. Roy Rico sabe sobre setReadable () y setWritable (), pero solo le permiten cambiar los permisos de propietario, no los permisos de grupo o de todos, o cualquiera de las otras banderas.
ChrisB
3

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

funciona bajo solaris / linux.

Vlad
fuente
uno debe tener en cuenta que FileSystemPreferenceslanza un Timerhilo de demonio una vez que está cargado. también agrega un gancho de apagado, pero para algunas aplicaciones esto puede resultar problemático.
jueves
2

Apache ant chmod (no muy elegante, agregándolo para completar) crédito compartido 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();
ihadanny
fuente
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();
        }     

Referencia: cómo cambiar el permiso del archivo en java

Anuj Dhiman
fuente
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
fuente