2

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

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

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

以原子方式执行此操作的最佳方法是什么,而不是在发生某些事情时冒着损坏该文件的风险?

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

提前致谢。

4

3 回答 3

5

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

如果您想要快速的原子追加,您可以使用fwriteandfsync来获得所达到的效果。fwrite小于 PIPE_BUF(iOS 上为 4096 字节)的 sfsync保证是原子的。

这是将执行该操作的类别的简短片段,请注意它缺少系统调用的正确错误检查代码。

@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
于 2012-05-17T13:03:56.880 回答
0

这里显示了一种方法,这个堆栈溢出问题也显示类似。

第二种方法是:

从文件中获取数据

 NSMutable *data = [NSData dataWithContentsOfFile:yourFilePath];
 [data appendData:yourNewData];
 [data writeToFile:yourFilePath];

第一个更可取,因为文件很厚。

希望这可以帮助 :)

于 2012-05-17T12:48:33.780 回答
0

看看NSFileHandle。它将允许您打开一个文件进行写入,将光标定位到文件的末尾,然后将您的数据附加到文件的末尾。

于 2012-05-17T13:25:18.720 回答