【问题标题】:Don't Save to File if file exists NSFileManager如果文件存在,不要保存到文件 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");

我怎样才能做到这一点?

【问题讨论】:

    标签: ios nsfilemanager


    【解决方案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 似乎无法轻松做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多