views:

165

answers:

3

Is it possible (on iPhone/iPod Touch) for a file written like this:


if (FILE* file = fopen(filename, "wb")) {
    fwrite(buf, buf_size, 1, file);
    fclose(file);
}

to get corrupted, e.g. when app is forced to terminate?

From what I know fwrite should be an atomic operation, so when I write whole file with one instruction no corruption should occure. I could not find any information on the net that would say otherwise.

+1  A: 

You could make things easier for yourself and write the data using the NSData class that has a writeToFile:atomically: method waiting for you. Wrapping the raw buffer with NSData is not hard, there are the dataWithBytes:length or dataWithBytesNoCopy:length:freeWhenDone: initializers.

zoul
+1  A: 

Data written with fwrite is buffered. So a sudden termination might not flush the buffers. fclose will flush the buffer but this does not implicate that the bytes are also written to the disk (due to OS level caches) AFAIK.

Diederik Hoogenboom
fclose will flush the buffer, am I wrong? And not flushing the buffer shouldn't corrupt the file.
sfider
fclose will indeed also flush the buffer.
Diederik Hoogenboom
@sfider: not flushing the buffer *will* corrupt the file. Example: assume the buffer is 512 bytes, and your data is 1200 bytes. fwrite would write the first 1024 bytes to disk, and leave the remaining 176 bytes in the buffer. Thus the file is incomplete and likely corrupt.
oefe
+1  A: 

Since when fwrite is atomic? I can't find any references. Anyway, even if fwrite can be atomic, the time between fopen and fwrite is not, so if your app is forced to terminate between those times, you'll get an empty file.

As you're writing for iPhoneOS, you can use -[NSData writeToFile:atomically:] to ensure the whole open-write-close procedure is atomic (it works by writing to a temporary file, then replace the original one.)

KennyTM
iPhoneOS derives from Mac OS X, Mac OS X is fully POSIX-compliant, and POSIX standard requires that C stdio FILE* operations are atomic.However you are right that I can have corruption if fwrite won't be called after fopen. I'll have to check this.
sfider