简体   繁体   中英

append NSString to file atomically?

some functions to write files are atomic and therefore quite convenient in the sense that they prevent file corruption should something happen at write-time.

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

the problem is that they erase the file and replace it with the new content… And I need to just append one line to a huge file.

What is the best way to do that in an atomic way, not risking to corrupt that file should something happen?

PS: the file is too huge to read it in one string, update the string and then push the enormous string to the file system.

Thanks in advance.

The reason there is no function like that is because the atomic versions makes a copy of the file, writes everything to it and then renames the new file to the same name as the old one and finally removes the old file. As such the original file is actually never modified but rather replaced with a new file.

If you want atomic appends that are fast, you can use fwrite and fsync to get the acheived effect. fwrite s that are for less than PIPE_BUF (4096 bytes on iOS) followed by fsync are guaranteed to be atomic.

Here is a short snippet for a category that will do the operation, note that it misses proper error-checking code for the syscalls.

@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

There is one way is shown here and this stack overflow question is also showing similar.

Second way to do that is:

get the data from the file

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

The first one is more preferable as the file is hudge.

Hope this helps :)

Take a look at NSFileHandle . It will allow you to open a file for write, seek the cursor to the end of the file, and then append your data to the end of the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM