我使用以下代码创建NSSavePanel
:
NSSavePanel *savePanel = [NSSavePanel savePanel];
savePanel.delegate = self;
savePanel.directoryURL = ...;
savePanel.nameFieldStringValue = ...;
[savePanel beginSheetModalForWindow:self.window
completionHandler:^(NSInteger returnCode) {
if (returnCode == NSFileHandlingPanelOKButton) {
// the completion handler
}
}];
如果在保存面板中用户选择了现有文件,则会出现警告框“”XXX“已存在。是否要替换它?”。
如果用户按下“替换”按钮,则在完成处理程序中使用removeItemAtPath:error:
NSFileManager
方法删除旧文件,然后创建新文件(实际上:它是在临时位置创建,然后使用moveItemAtPath:toPath:error:
方法移动,但我认为这只是一个实现细节):
if (returnCode == NSFileHandlingPanelOKButton) {
// overwrite the url, because if we are here is because the user has already
// expressed its willingness to overwrite the previous file
NSError *error = nil;
BOOL res = [[NSFileManager defaultManager] removeItemAtURL:savePanel.URL error:&error];
if (res) {
res = [[NSFileManager defaultManager] moveItemAtPath:tmpFilePath toPath:savePanel.URL error:&error];
}
// ...
}
过去,一切都运作正常。然而,今天,我开始使用具有“读/写访问权限”权利的Lion's Sandbox。
使用沙箱,removeItemAtPath:error:
成功,但以下moveItemAtPath:toPath:error:
会返回错误。
这似乎很合理,因为Powerbox授予我访问(读写)文件的权限。当我删除此文件时,授予我的权利已经用尽。
我猜对了吗?
我该如何解决这个问题?
答案 0 :(得分:1)
问题是,一旦删除该文件,您对该文件的权利也会消失。您需要做的是覆盖文件,例如使用[[NSFileManager defaultManager] createFileAtPath:contents:attributes:]
。 NSFileManager documentation说明了此方法的以下内容:
如果路径中已存在某个文件,则此方法会覆盖该文件的内容(如果当前进程具有相应的权限)。
使用NSData
/ NSMutableData
中的方法也可能会有所帮助。
答案 1 :(得分:0)
使用[NSFileHandle fileHandleForWritingToURL:error:]后跟writeData:调用覆盖现有文件。这个方法适用于沙盒应用程序。对于新文件,只需使用NSFileManager的方法createFileAtPath创建它:contents:attributes :(如果内容不适合内存,则将内容设置为nil)然后使用NSFileHandle写入数据。
如果您想使用核心图形覆盖图像,请参阅NSSavePanel, CGImageDestinationFinalize and OS X sandbox