Como altero as permissões do arquivo de forma programática?


115

Em Java, estou criando dinamicamente um conjunto de arquivos e gostaria de alterar as permissões de arquivo nesses arquivos em um sistema de arquivos linux / unix. Eu gostaria de poder executar o equivalente em Java de chmod. Isso é possível Java 5? Se sim, como?

Eu sei que em Java 6 o Fileobjeto tem setReadable()/ setWritable()métodos. Também sei que posso fazer uma chamada de sistema para fazer isso, mas gostaria de evitar isso, se possível.


2
Observação para outros: para arquivos existentes, desde o Java 7, você pode usar este one-liner:Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"))
tom

Respostas:


110

O controle total sobre os atributos do arquivo está disponível no Java 7, como parte do "novo" recurso New IO ( NIO.2 ). Por exemplo, as permissões POSIX podem ser definidas em um arquivo existente com setPosixFilePermissions(), ou atomicamente na criação do arquivo com métodos como createFile()ou newByteChannel().

Você pode criar um conjunto de permissões usando EnumSet.of(), mas o método auxiliar PosixFilePermissions.fromString()usará um formato convencional que será mais legível para muitos desenvolvedores. Para APIs que aceitam um FileAttribute, você pode agrupar o conjunto de permissões com PosixFilePermissions.asFileAttribute().

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

Em versões anteriores do Java, usar seu próprio código nativo ou executilitários de linha de comando -ing são abordagens comuns.


4
selecionando este porque não tenho a capacidade de usar a resposta de Marty Lamb.
Roy Rico,

1
Eu realmente não posso acreditar que já se passaram mais de seis anos desde que eles começaram a trabalhar no NIO.2 e ainda não está em um JRE comercial.
clee

8
O exemplo de código pode ser útil em sua resposta.
Ricardo Gladwell

2
Esta resposta stackoverflow.com/a/32331442/290182 por @PixelsTech é superior, pois fornece um código de exemplo
beldaz

1
@SteveB Tudo pronto.
Erickson

43

Além das sugestões de erickson, há também o jna , que permite chamar bibliotecas nativas sem usar o jni. É surpreendentemente fácil de usar e usei-o em alguns projetos com grande sucesso.

A única ressalva é que ele é mais lento do que jni, portanto, se você estiver fazendo isso com um número muito grande de arquivos, pode ser um problema para você.

(Editando para adicionar exemplo)

Aqui está um exemplo 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);
}

1
JNA é uma ferramenta tão boa para chamadas nativas!
Erickson,

3
Para o tratamento correto de erros, CLibrary.chmod () deve ser declarado para lançar com.sun.jna.LastErrorException. Essa é a única maneira thread-safe de obter o valor errno definido pela chamada chmod (). Caso contrário, você pode obter o status de sucesso / falha do valor de retorno, mas não o código de erro real.
Simon Kissane,

30

Antes do Java 6, não havia suporte para atualização de permissão de arquivo no nível do Java. Você deve implementar seu próprio método nativo ou chamada Runtime.exec()para executar um comando de nível de sistema operacional, como chmod .

A partir do Java 6, você pode usar File.setReadable()/File.setWritable()/File.setExecutable()para definir permissões de arquivo. Mas não simula o sistema de arquivos POSIX, que permite definir permissões para diferentes usuários. File.setXXX () só permite definir permissão para o proprietário e todos os outros.

A partir do Java 7, é introduzida a permissão de arquivo POSIX. Você pode definir permissões de arquivo como o que fez nos sistemas * nix. A sintaxe é:

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 só pode ser usado no sistema de arquivos POSIX, isso significa que você não pode chamá-lo no sistema Windows.

Para obter detalhes sobre o gerenciamento de permissões de arquivos, recomendamos que você leia esta postagem .


18

para windows 7 com 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
isso funciona muito bem. A única modificação feita foi no método lookupPrincipalByName (), enviei System.getProperty ("user.name") em vez de "user". Por fim, parecia upls.lookupPrincipalByName (System.getProperty ("user.name")); Obrigado pelo código!
isuru chathuranga

@bob .. você pode me dar a classe AclFileAttributeView e UserPrincipalLookupService .. bcz não consigo resolver .. sua resposta parece estar funcionando .. e eu quero implementar
Sagar Chavada

java.nio.file.attribute.AclFileAttributeView e java.nio.file.attribute.UserPrincipalLookupService, requer jdk 1.7+ para compilar e executar.
bob

11

Se você deseja definir a permissão 777 para o arquivo criado, pode usar o seguinte 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);
}

10

Apenas para atualizar esta resposta, a menos que alguém descubra isso mais tarde, já que JDK 6 você pode

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

você pode encontrar a documentação no arquivo Oracle (Java Platform SE 7) . Lembre-se de que esses comandos só funcionam se o usuário atual tiver propriedade ou acesso de gravação a esse arquivo. Estou ciente de que OP queria acesso do tipo chmod para configurações de usuário mais complexas. isso definirá a opção em todos os níveis para todos os usuários.


Legal, le sauveur!
khawarizmi de

Eu testei ainda com Openjdk 11.0.6 no Debian, ele funciona!
Hartmut Schorrig


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 em solaris / linux.


deve-se estar ciente de que FileSystemPreferencesexpande um Timerthread daemon depois de carregado. ele também adiciona um gancho de desligamento, mas para alguns aplicativos isso ainda pode ser problemático.
quinta

2

Crédito do Apache ant chmod (não muito elegante, adicionando-o para integridade) compartilhado com @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();
        }     

Referência: como alterar a permissão do arquivo em 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);
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.