NSFileManager & NSFilePosixPermissions

Я хочу использовать восьмеричные разрешения (используемые для chmod) для NSFilePosixPermissions. Вот что я сделал сейчас:

NSFileManager *manager = [NSFileManager defaultManager];
NSDictionary *atributes;

[atributes setValue:[NSString stringWithFormat:@"%d", 0777] 
             forKey:@"NSFilePosixPermissions"]; // chmod permissions 777
[manager setAttributes:atributes ofItemAtPath:@"/Users/lucky/Desktop/script" error:nil];

Я не получаю ошибки, но когда я проверяю результат с помощью "ls -o", разрешение не является -rwxrwxrwx.

В чем дело? Спасибо за помощь.

4 ответа

Решение

Первый, NSFilePosixPermissions это имя константы. Его значение также может быть одинаковым, но это не гарантировано. Значение NSFilePosixPermissions константа может меняться между выпусками фреймворка, например @"NSFilePosixPermissions" в @"posixPermisions", Это сломало бы ваш код. Правильный путь - использовать константу как NSFilePosixPermissionsне @"NSFilePosixPermissions",

Кроме того, ссылка NSFilePosixPermissions говорит о NSFilePosixPermisions:

Соответствующее значение является NSNumber объект. Использовать shortValue метод для получения целочисленного значения для разрешений.

Правильный способ установки разрешений POSIX:

// chmod permissions 777

// Swift
attributes[NSFilePosixPermissions] = 0o777

// Objective-C
[attributes setValue:[NSNumber numberWithShort:0777] 
             forKey:NSFilePosixPermissions];

Решение в Свифте 3

let fm = FileManager.default

var attributes = [FileAttributeKey : Any]()
attributes[.posixPermissions] = 0o777
do {
    try fm.setAttributes(attributes, ofItemAtPath: path.path)
}catch let error {
    print("Permissions error: ", error)
}

Решение в Swift 4

Я попытался использовать 0o777, и это не изменило файл только для чтения. Я считаю, что правильный способ сделать это заключается в следующем:

let fileManager = FileManager.default

let documentsUrl: URL = self.fileManager.urls(for: .documentDirectory, in: .userDomainMask).first as URL!

let destinationFileUrl = documentsUrl.appendingPathComponent(fileName)

let readOnlyAttribute: [FileAttributeKey: Any] = [
            .posixPermissions: 0777
        ]
do {       

    try fileManager.setAttributes(readOnlyAttribute, ofItemAtPath: destinationFileUrl.path)

    if fileManager.isWritableFile(atPath: destinationFileUrl.path) {
        print("writeable")
    } else {
        print("read only")
    }

} catch let error {

    print("Could not set attributes to file: \(error.localizedDescription)")
}

Теперь есть тип FilePermissions , который может упростить эту задачу.

Вы можете добавить расширение:

      extension FileManager {

  func setUnixPermissions(_ permissions: FilePermissions, atPath: String) throws {
    try FileManager.default.setAttributes(
      [.posixPermissions: permissions.rawValue],
      ofItemAtPath: atPath
    )
  }

}

Пример использования:

        let fm = FileManager.default
  let path = "/path/to/something"

  // FilePermissions.
  try fm.setUnixPermissions([.ownerRead, .groupRead], atPath: path)

  // Octal permissions.
  try fm.setUnixPermissions(FilePermissions(rawValue: 0x777), atPath: path)

Другие вопросы по тегам