iosnsdatafseeknsfilehandlensoutputstream

create an empty file of specific size and write new data to specific position with fseek


I am new to ios I have 10 chunks of 1024 bytes. this chunks are not in order. If i know the number of chunk how can i insert the data in a file of size 10*1024? So far i have the following code:

//method called when new chunk arrvies


 NSArray *paths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    //create a file name to write the data to using the documents directory:
    filePath = [NSString stringWithFormat:@"%@/example.txt", 
                documentsDirectory];

    NSFileHandle *writeFile = [NSFileHandle fileHandleForWritingToURL:filePath error:nil];
    [writeFile truncateFileAtOffset:10240*sizeof(Byte)];

How to add new data using fseek?

I did try to use the following code:

if ((chunkNo == 0 )||(chunkNo == 10))
    {
        NSOutputStream *stream = [[NSOutputStream alloc] initToFileAtPath:filePath append:YES];
        [stream open];
        NSData *chunk = chunkContainer; // some data
        [stream write:(uint8_t *)[chunk bytes] maxLength:[chunk length]];
        [stream close];

    }
    else{
        NSData *chunk = chunkContainer; // some data
        NSUInteger insertPoint = chunkNo*1024; // get the insertion point //
        // make sure the file exists, if it does, do the following //
        NSData *oldData = [NSData dataWithContentsOfFile:filePath];

        NSOutputStream *stream = [[NSOutputStream alloc] initToFileAtPath:filePath append:NO];
        [stream open];
        [stream write:(uint8_t *)[oldData bytes] maxLength:insertPoint]; // write the old data up to the insertion point //
         [stream write:(uint8_t *)[chunk bytes] maxLength:[chunk length]]; // write the new data //
         [stream write:(uint8_t *)([oldData bytes]+insertPoint) maxLength:([oldData length]-insertPoint)]; // write the rest of old data at the end of the file //

        [stream close];
    }

BUT the result file is not fully correct, if the chunks are not in the right order. If the chunks are in the right order, than the result file is correctly displayed.


Solution

  • Example:

    NSString *filePath = [@"~/Desktop/FHTest.txt" stringByExpandingTildeInPath];
    
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:[NSData new] attributes:nil];
    NSFileHandle *fh;
    
    NSData *data1 = [@"test Data" dataUsingEncoding:NSUTF8StringEncoding];
    fh = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [fh writeData:data1];
    [fh closeFile];
    
    NSData *data2 = [@"more Data" dataUsingEncoding:NSUTF8StringEncoding];
    fh = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [fh seekToFileOffset:100];
    [fh writeData:data2];
    [fh closeFile];
    

    Note that the seekToFileOffset:100 will fill expand the file as necessary filling as necessary with 0x00 bytes.

    To create a file of specific size, in this case 100 bytes:

    unsigned long long size = 100;
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:[NSData new] attributes:nil];
    NSFileHandle *fh = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [fh seekToFileOffset:size-1];
    [fh writeData:[@"\x00" dataUsingEncoding:NSUTF8StringEncoding]];
    [fh closeFile];