Overwrite Data using NSFileHandle
Asked Answered
M

1

13

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:

Monoclinous answered 20/2, 2015 at 2:2 Comment(0)
M
12

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.

Monoclinous answered 20/2, 2015 at 21:4 Comment(1)
This is a nice solution. I would suggest updating the signature of the method to be: -(void)removeCharacters:(unsigned long long)numberOfCharacters fromBeginningOfFile:(NSFileHandle*)fileHandle {Bookkeeper

© 2022 - 2024 — McMap. All rights reserved.