将NSString以原子方式附加到文件中?

Mik*_*elW 2 iphone file atomic objective-c

一些写文件的函数是原子的,因此在写入时发生某些事情时它们可以防止文件损坏.

-[NSData writeToFile:atomically:]
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
Run Code Online (Sandbox Code Playgroud)

问题是他们擦除文件并用新内容替换它...我需要在一个巨大的文件中附加一行.

以原子方式执行此操作的最佳方法是什么,而不是冒着损坏该文件的风险?

PS:文件太大而无法在一个字符串中读取它,更新字符串然后将巨大的字符串推送到文件系统.

提前致谢.

Ham*_*son 5

没有这样的功能的原因是因为原子版本制作文件的副本,将所有内容写入其中,然后将新文件重命名为与旧文件相同的名称,最后删除旧文件.因此,原始文件实际上从未被修改,而是被替换为新文件.

如果你想要快速的原子追加,你可以使用fwritefsync获得实现的效果.fwrites小于PIPE_BUF(iOS上为4096字节)后跟fsync保证是原子的.

这是一个用于执行操作的类别的简短代码段,请注意它错过了系统调用的正确错误检查代码.

@implementation NSData(AppendAtomically)

- (void)appendToFileAtomic:(NSString *)filePath
{
    NSAssert([self length] < PIPE_BUF, @"Cannot write messages longer than %d atomically", PIPE_BUF);

    const char *utfpath = [filePath UTF8String]; 

    FILE *f = fopen(utfpath, "ab");
    fwrite([self bytes], 1, [self length], f);
    fsync(fileno(f));
    fclose(f);
}

@end
Run Code Online (Sandbox Code Playgroud)