NSFileManager & NSFilePosixPermissions

7

我想在NSFilePosixPermissions中使用八进制权限(用于chmod)。 以下是我现在所做的:

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

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

我没有收到错误提示,但是当我使用“ls -o”检查结果时,权限不是-rwxrwxrwx。

有什么问题吗? 谢谢您的帮助。

3个回答

18

首先,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];

2
您还可以使用字面量表示法来传递NSNumber(和NSDictionary):@{NSFilePosixPermissions: @0777} - Matthemattics
1
请注意,这里的前导零非常重要。它告诉C编译器您的常量是八进制的。八进制0777在十进制中为511,而不是相同的数字! - Duncan C
你说一个short。如果我想要的八进制是0100640而不是0640呢?这是C版本的chmod()的一个完全有效的八进制。然而,C的short只能存储最多32767(有符号)或65535(无符号)的数字。这不足以存储0100640。 - Volomike
不,这不是我在说。苹果公司说的。此外,这个属性与文件权限有关。0100000不是一个权限位,它只是模式的一部分。权限只是模式的一个子集。 - gcbrueckmann
添加了一个Swift示例。请注意,您无需在“NSNumber”中显式包装该值。Swift-Objective-C桥接将自动执行此操作。 - gcbrueckmann
显示剩余3条评论

4

使用Swift 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)
}

0
现在有一个文件权限类型,可以使这个过程更容易。
你可以添加一个扩展:
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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接