如果文件存在,不要保存到文件 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 的回答,但显然,如果 save
是 NSString
,您可以稍微简化一下:
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的主要内容,如果未能解决你的问题,请参考以下文章