Can't set offset of a file NSOutputStream with appending enabled

  • Hi, all.

    I tried to set the offset property of a file NSOutputStream by NSStreamFileCurrentOffsetKey with appending enabled with code listed below. But it doesn't work.

    The output is "1234567890abcdefghij!@#$%^&*()ABCDEFGHIJ" as s1 plus s2 if you remove output.txt before running this demo program. The setProperty:forKey returns NO and querying of the NSStreamFileCurrentOffsetKey property returns nil. I've tried the Core Foundation counterpart CFWriteStreamSetProperty with kCFStreamPropertyFileCurrentOffset, but no magic happens.

    If appending is disabled, everything is fine. But I don't want to replace the original file. The document says that NSStreamFileCurrentOffsetKey allows me to manipulate the current read or write position in file-based streams. So I wonder why this operation failed.

    NSString *s1 = @"1234567890abcdefghij";
    NSString *s2 = @"!@#$%^&*()ABCDEFGHIJ";
    char *cwd = getcwd(NULL, 0);
    NSString *currentWD = [NSString stringWithCString:cwd encoding:NSASCIIStringEncoding];
    free(cwd);

    NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:[currentWD stringByAppendingPathComponent:@"output.txt"] append:YES];
    [outStream open];
    [outStream write:(const uint8_t *)[s1 UTF8String] maxLength:[s1 length]];
    NSLog(@"Current file offset: %@", [outStream propertyForKey:NSStreamFileCurrentOffsetKey]);
    BOOL result = [outStream setProperty:@(0) forKey:NSStreamFileCurrentOffsetKey];
    NSLog(@"result is %d, %@", result, [outStream streamError]);
    NSLog(@"Current file offset: %@", [outStream propertyForKey:NSStreamFileCurrentOffsetKey]);
    [outStream write:(const uint8_t *)[s2 UTF8String] maxLength:[s2 length]];
    [outStream close];

    Thanks,
    Hank
  • On Jun 4, 2013, at 12:32 PM, Hank Bao wrote:

    > I tried to set the offset property of a file NSOutputStream by NSStreamFileCurrentOffsetKey with appending enabled with code listed below.

    Appending isn't "enabled", per se, it's a mode for the underlying file descriptor that forces data to always be appended to the end of the file.  See the open() system call and O_APPEND for the low-level equivalent.

    What you're looking for is opening for writing without truncating.  It doesn't seem as though NSOutputStream supports that.  You may want to look into NSFileHandle instead.

    > The document says that NSStreamFileCurrentOffsetKey allows me to manipulate the current read or write position in file-based streams.

    That probably means that you can seek within a write stream for a file opened and truncated (after you've written some data, of course).

    Regards,
    Ken
  • On Jun 4, 2013, at 10:32 AM, Hank Bao <hankbao84...> wrote:

    > I tried to set the offset property of a file NSOutputStream by NSStreamFileCurrentOffsetKey with appending enabled with code listed below. But it doesn't work.

    FYI, I’ve rarely found it useful to use NSStream or NSFileHandle for file I/O. Instead I just use the standard C library calls (fopen, fread, etc.) or the POSIX calls (open, read, etc.) I find them easier to use, more flexible, and of course cross-platform.

    —Jens
previous month june 2013 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today