Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overwrite Data using NSFileHandle

Using an NSFileHandle, it is pretty easy to remove n number of characters from the end of the file using truncateFileAtOffset.

-(void)removeCharacters:(int)numberOfCharacters fromEndOfFile:(NSFileHandle*)fileHandle {
    unsigned long long fileLength = [fileHandle seekToEndOfFile];
    [fileHandle truncateFileAtOffset:fileLength - numberOfCharacters];
}

However removing characters from the front of the file doesn't seem possible without having to copy all of the remaining data into memory, overwriting the file and then writing the remaining data back into the file.

-(void)removeCharacters:(int)numberOfCharacters fromBeginningOfFile:(NSFileHandle*)fileHandle {
    [fileHandle seekToFileOffset:numberOfCharacters];

    NSData *remainingData = [fileHandle readDataToEndOfFile];
    [fileHandle truncateFileAtOffset:0];
    [fileHandle writeData:remainingData];
}

This code works, but will become a liability with large files. What am I missing?

Ideally I'd like to be able to do replaceCharactersInRange:withData:

like image 615
Casey Avatar asked Feb 20 '15 02:02

Casey


1 Answers

After playing around more with NSFileHandle it became clear that insertion without overwriting is impossible.

As explained in: Inserting a string at a specified line in text file using objective c "you can only grow a file at the end; not in the middle."

Here is a slightly more optimized version of the above code:

-(void)removeCharacters:(unsigned long long)numberOfCharacters fromBeginningOfFile:(NSFileHandle*)fileHandle {
    [fileHandle seekToFileOffset:numberOfCharacters];

    NSData *remainingData = [fileHandle readDataToEndOfFile];
    [fileHandle seekToFileOffset:0];
    [fileHandle writeData:remainingData];
    [fileHandle truncateFileAtOffset:remainingData.length];
}

I more involved solution would be to buffer the file into another file in chunks. This would mitigate memory concerns.

like image 124
Casey Avatar answered Oct 11 '22 15:10

Casey