Вопрос-ответ

How do I programmatically change file permissions?

Как мне программно изменить права доступа к файлам?

В Java я динамически создаю набор файлов, и я хотел бы изменить права доступа к этим файлам в файловой системе Linux / unix. Я хотел бы иметь возможность выполнять Java-эквивалент chmod. Возможно ли это на Java 5? Если да, то каким образом?

Я знаю, что в Java 6 у File объекта есть методы setReadable()/setWritable() . Я также знаю, что мог бы выполнить системный вызов для этого, но я бы хотел избежать этого, если возможно.

Переведено автоматически
Ответ 1

Полный контроль над атрибутами файла доступен в Java 7 как часть "нового" средства ввода-вывода (NIO.2). Например, разрешения POSIX могут быть установлены для существующего файла с помощью setPosixFilePermissions(), или атомарно при создании файла с помощью таких методов, как createFile() или newByteChannel().

Вы можете создать набор разрешений с помощью EnumSet.of(), но вспомогательный метод PosixFilePermissions.fromString() будет использовать обычный формат, который будет более удобочитаемым для многих разработчиков. Для API, которые принимают FileAttribute, вы можете обернуть набор разрешений с помощью PosixFilePermissions.asFileAttribute().

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

В более ранних версиях Java обычным подходом было использование собственного машинного кода или exec утилит командной строки.

Ответ 2

До Java 6 обновление прав доступа к файлам на уровне Java не поддерживалось. Вы должны реализовать свой собственный собственный метод или вызвать Runtime.exec() для выполнения команды уровня операционной системы, такой как chmod.

Начиная с Java 6, вы можете использоватьFile.setReadable()/File.setWritable()/File.setExecutable() для установки прав доступа к файлам. Но это не имитирует файловую систему POSIX, которая позволяет устанавливать права доступа для разных пользователей. File.setXXX() позволяет устанавливать права доступа только для владельца и всех остальных.

Начиная с Java 7, вводятся права доступа к файлам POSIX. Вы можете установить права доступа к файлам, подобные тому, что вы сделали в системах * nix. Синтаксис таков :

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

Этот метод можно использовать только в файловой системе POSIX, это означает, что вы не можете вызвать его в системе Windows.

Для получения подробной информации об управлении правами доступа к файлам рекомендую вам прочитать этот пост.

Ответ 3

В дополнение к предложениям Эриксона, существует также jna, которая позволяет вызывать собственные библиотеки без использования jni. Он потрясающе прост в использовании, и я с большим успехом использовал его в паре проектов.

Единственное предостережение заключается в том, что это медленнее, чем jni, поэтому, если вы делаете это с очень большим количеством файлов, это может быть проблемой для вас.

(Редактирование для добавления примера)

Вот полный пример 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);
}
Ответ 4

Для Windows 7 с NIO 2:

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()));
}
2023-06-26 08:58 java