如果文件存在,不要保存到文件 NSFileManager

Posted

技术标签:

【中文标题】如果文件存在,不要保存到文件 NSFileManager【英文标题】:Don't Save to File if file exists NSFileManager 【发布时间】:2013-01-30 07:45:36 【问题描述】:

我有一个 NSFileManager 来搜索文件,如果文件不存在,它会创建一个文件,如果文件存在,它会写入文件。但我想要的是,如果文件存在,它就不会写入它。这是我的代码。

NSString *docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSLog(@"%@", docPath);
NSString *results=[docPath stringByAppendingPathComponent:@"results.csv"];

if (![[NSFileManager defaultManager] fileExistsAtPath:results]) 
    [[NSFileManager defaultManager]
     createFileAtPath:results contents:nil attributes:nil];

NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:results];
[fileHandle seekToEndOfFile];
[fileHandle writeData:[save dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandle closeFile];
NSLog(@"info saved");

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

您应该接受 Flexicoder 的回答,但显然,如果 saveNSString,您可以稍微简化一下:

NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *results = [docPath stringByAppendingPathComponent:@"results.csv"];

if (![[NSFileManager defaultManager] fileExistsAtPath:results])
    [save writeToFile:results atomically:YES encoding:NSUTF8StringEncoding error:nil];

【讨论】:

不是线程安全的;有一个潜在的竞争条件,当调用 fileExistsAtPath: 时文件不存在,但在调用 writeToFile: 时文件确实存在,并被覆盖。我正在寻找一个线程安全的解决方案来解决这个问题;令人困惑的是,Cocoa API 似乎无法轻松做到这一点。 @bhaller - 转换为NSData,然后使用带有“no overwrite”选项的writetofile:options:error: 是的,我最终发现了——尽管据我所知,文档实际上并不能保证操作是原子的。也许该选项只是为您调用fileExistsAtPath:,并且有同样的问题。 它不是原子的。而且我相信它不只是打电话给fileExists。这是一个很好理解的问题,这就是该选项的全部目的。另一种方法是在完成后写入临时文件和move it。或者考虑developer.apple.com/documentation/foundation/nsfilemanager/… 等等,你说它不是原子的,但你也说解决这个竞争条件是“那个选项的全部目的”?怎么可能两者兼而有之?它要么通过原子性解决问题,要么不……不?【参考方案2】:

将所有代码包含在 if 语句中

NSString *docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSLog(@"%@", docPath);
NSString *results=[docPath stringByAppendingPathComponent:@"results.csv"];

if (![[NSFileManager defaultManager] fileExistsAtPath:results]) 
    [[NSFileManager defaultManager]
 createFileAtPath:results contents:nil attributes:nil];
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:results];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:[save dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandle closeFile];
    NSLog(@"info saved");

【讨论】:

不是线程安全的;有一个潜在的竞争条件,当调用 fileExistsAtPath: 时文件不存在,但在调用 createFileAtPath: 时文件确实存在,并被覆盖。我正在寻找一个线程安全的解决方案来解决这个问题;令人困惑的是 NSFileManager API 似乎无法轻松做到这一点。

以上是关于如果文件存在,不要保存到文件 NSFileManager的主要内容,如果未能解决你的问题,请参考以下文章

excel 恢复忘记保存的文档

如果文件存在,如何锁定文件,不要创建它?

使用覆盖将图像保存到文档目录

如果文件已经存在,ffmpeg 重命名输出

vb.net 怎么判断一个文件夹或是文本文件的存在?如果没有则创建……求代码!不要VB6.0的

多实例集群部署下的图片上传