Reading Files in Objective-C

Our first program will demonstrate reading files. Here’s the full source code:

#import <Foundation/Foundation.h>

// Helper function to check for errors
void check(NSError *error) {
    if (error != nil) {
        @throw [NSException exceptionWithName:NSGenericException
                                       reason:[error localizedDescription]
                                     userInfo:nil];
    }
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSError *error = nil;
        NSString *filePath = @"/tmp/dat";
        
        // Read entire file content
        NSString *fileContent = [NSString stringWithContentsOfFile:filePath
                                                         encoding:NSUTF8StringEncoding
                                                            error:&error];
        check(error);
        NSLog(@"%@", fileContent);
        
        // Open file for reading
        NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
        if (fileHandle == nil) {
            NSLog(@"Failed to open file");
            return 1;
        }
        
        // Read some bytes from the beginning of the file
        NSData *data = [fileHandle readDataOfLength:5];
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%lu bytes: %@", (unsigned long)[data length], str);
        
        // Seek to a known location and read from there
        [fileHandle seekToFileOffset:6];
        data = [fileHandle readDataOfLength:2];
        str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%lu bytes @ %llu: %@", (unsigned long)[data length], [fileHandle offsetInFile], str);
        
        // Seek relative to current position
        [fileHandle seekToFileOffset:[fileHandle offsetInFile] + 4];
        
        // Seek relative to end of file
        [fileHandle seekToEndOfFile];
        [fileHandle seekToFileOffset:[fileHandle offsetInFile] - 10];
        
        // Use NSInputStream for buffered reading
        NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:filePath];
        [inputStream open];
        uint8_t buffer[5];
        NSInteger bytesRead = [inputStream read:buffer maxLength:5];
        str = [[NSString alloc] initWithBytes:buffer length:bytesRead encoding:NSUTF8StringEncoding];
        NSLog(@"5 bytes: %@", str);
        
        [inputStream close];
        [fileHandle closeFile];
    }
    return 0;
}

This program demonstrates various file reading operations in Objective-C:

  1. We start by reading the entire file content using NSString’s stringWithContentsOfFile:encoding:error: method.

  2. Then we open the file using NSFileHandle for more controlled reading operations.

  3. We read a specific number of bytes from the beginning of the file.

  4. We demonstrate seeking to different positions in the file using seekToFileOffset:.

  5. We use NSInputStream for buffered reading, which can be more efficient for many small reads.

To run the program, save it as ReadingFiles.m and compile it using:

$ clang -framework Foundation ReadingFiles.m -o ReadingFiles

Before running the program, create a test file:

$ echo "hello" > /tmp/dat
$ echo "go" >> /tmp/dat

Now you can run the compiled program:

$ ./ReadingFiles

The output will depend on the content of your /tmp/dat file, but it should display the file content and the results of various read operations.

Next, we’ll look at writing files.