You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift复制目录访问权限时设置URL.fileSecurityKey报错咨询

问题

我尝试将源目录的访问权限复制到目标目录,Finder信息面板显示:

  • 源目录权限:「我:读写;所有人:无访问」
  • 目标目录原权限:「我:读写;Staff:只读;所有人:只读」

使用以下Swift代码可在目标目录创建文件,但设置URL.fileSecurityKey资源时失败,报错信息为「您没有权限将文件“destination”保存在文件夹“parent”中」。我认为运行在用户权限下的应用应拥有相同权限,且我对两个目录均有读写权限,为何仍出现此问题?

代码:

let openPanel = NSOpenPanel()
openPanel.canChooseDirectories = true
openPanel.canChooseFiles = false
openPanel.runModal()
let source = openPanel.urls[0]
openPanel.runModal()
var destination = openPanel.urls[0]
do {
    try Data().write(to: destination.appendingPathComponent("asd"))
    try destination.setResourceValues(source.resourceValues(forKeys: [.fileSecurityKey]))
} catch {
    fatalError(error.localizedDescription)
}
分析与解决

核心原因

直接复制完整的fileSecurity会覆盖目标目录的继承权限设置,macOS中目录权限通常会继承父文件夹的属性。当你把源目录「所有人:无访问」的完整权限直接应用到目标目录时,会破坏目标目录原本的继承关系,系统判定该操作超出当前用户权限范围——哪怕你对目标目录本身有读写权限。

另外,fileSecurityKey包含完整的POSIX权限+ACL规则,直接复制会让目标目录丢失原本从父目录继承的ACL条目,这些条目可能包含系统或其他用户的必要权限设置,触发系统的权限保护机制。

解决方法

不要直接复制完整的fileSecurity,提取并复制核心权限部分即可:

  1. 从源目录获取POSIX权限、所有者及组所有者信息
  2. 仅将这些核心权限应用到目标目录,保留目标目录原本的继承ACL规则

修改后的代码示例:

let openPanel = NSOpenPanel()
openPanel.canChooseDirectories = true
openPanel.canChooseFiles = false
openPanel.runModal()
let source = openPanel.urls[0]
openPanel.runModal()
let destination = openPanel.urls[0]

do {
    // 创建测试文件验证基础读写权限
    try Data().write(to: destination.appendingPathComponent("asd"))
    
    // 获取源目录核心权限信息
    let sourceValues = try source.resourceValues(forKeys: [.posixPermissionsKey, .ownerAccountIDKey, .groupOwnerAccountIDKey])
    
    // 构建目标目录权限设置(仅覆盖核心项,保留继承属性)
    var destValues = URLResourceValues()
    destValues.posixPermissions = sourceValues.posixPermissions
    destValues.ownerAccountID = sourceValues.ownerAccountID
    destValues.groupOwnerAccountID = sourceValues.groupOwnerAccountID
    
    // 应用权限设置
    try destination.setResourceValues(destValues)
} catch {
    fatalError(error.localizedDescription)
}

补充说明

  • 若确实需要复制ACL规则,不要直接覆盖,先获取目标目录现有ACL,再合并源目录的必要条目,避免破坏继承关系
  • macOS权限系统(尤其是ACL)会结合父目录继承规则,直接替换完整fileSecurity会触发系统安全校验,即使是目录所有者也可能被阻止

内容的提问来源于stack exchange,提问作者Nickkk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:55:29