NSTask setStandardOutput: then stringWithContentsOfFile gives empty string

  • Why does the following log an empty string for the fileContents?

        NSString *path = @"/tmp/myFile.tmp";

        if ( [[NSFileManager defaultManager] fileExistsAtPath: path] )
        {
            [[NSFileManager defaultManager] removeFileAtPath: path
    handler: nil];
        }

        BOOL fileCreated = [[NSFileManager defaultManager]
    createFileAtPath: path contents: @"" attributes: nil];
        if ( fileCreated )
        {
            NSFileHandle *fileHandle = [NSFileHandle
    fileHandleForWritingAtPath: path];

            NSTask *myTask = [[NSTask alloc] init];
            [myTask setLaunchPath: @"/bin/ps"];
            [myTask setArguments: [NSArray arrayWithObject: @"axwww"]];
            [myTask setStandardOutput: fileHandle];
            [myTask launch];

            NSString *fileContents = [NSString stringWithContentsOfFile:
    path encoding: NSUTF8StringEncoding error: nil];
            NSLog(@"    fileContents = \"%@\"", fileContents);

            [myTask autorelease];
    }

    If I put a breakpoint at the top and step trough this code I do get
    the file contents in the NSString. However, if I run without
    breakpoints I get an empty string yet when I inspect /tmp/myFile.tmp
    via the Terminal, it has the expected content.

    Is there some file system flushing I need to do?

    Thanks,
    Gonzalo
  • At 3:43 PM -0400 8/27/07, Gonzalo Castro wrote:

    > [myTask launch];
    >
    > NSString *fileContents = [NSString stringWithContentsOfFile:
    > path encoding: NSUTF8StringEncoding error: nil];
    > NSLog(@"    fileContents = \"%@\"", fileContents);
    >
    > [myTask autorelease];
    > }
    >
    > If I put a breakpoint at the top and step trough this code I do get
    > the file contents in the NSString. However, if I run without
    > breakpoints I get an empty string yet when I inspect /tmp/myFile.tmp
    > via the Terminal, it has the expected content.
    >
    > Is there some file system flushing I need to do?

    My guess is, the task has not finished by the time the next line has
    executed.  By breaking in the debugger, and via Terminal inspection,
    the task has finished and the output available.  You can probably
    test this by putting a sleep() call after launch, but I'm not sure
    the best way to correctly handle the situation.

    Actually, yes, I do (after looking up NSTask in the dev docs).  After
    the [myTask launch], put a [myTask waitUntilExit] call; this will
    ensure the task has completed and any output you're expecting will be
    available.
  • I got the answer off-list. I needed to add the following after -
    launch so execution waits until the launch is finished.

                [myTask waitUntilExit];

    Thanks Dennis!

    Gonzalo

    On Aug 27, 2007, at 3:43 PM, Gonzalo Castro wrote:

    > Why does the following log an empty string for the fileContents?
    >
    > NSString *path = @"/tmp/myFile.tmp";
    >
    > if ( [[NSFileManager defaultManager] fileExistsAtPath: path] )
    > {
    > [[NSFileManager defaultManager] removeFileAtPath: path
    > handler: nil];
    > }
    >
    > BOOL fileCreated = [[NSFileManager defaultManager]
    > createFileAtPath: path contents: @"" attributes: nil];
    > if ( fileCreated )
    > {
    > NSFileHandle *fileHandle = [NSFileHandle
    > fileHandleForWritingAtPath: path];
    >
    > NSTask *myTask = [[NSTask alloc] init];
    > [myTask setLaunchPath: @"/bin/ps"];
    > [myTask setArguments: [NSArray arrayWithObject: @"axwww"]];
    > [myTask setStandardOutput: fileHandle];
    > [myTask launch];
    >
    > NSString *fileContents = [NSString
    > stringWithContentsOfFile: path encoding: NSUTF8StringEncoding
    > error: nil];
    > NSLog(@"    fileContents = \"%@\"", fileContents);
    >
    > [myTask autorelease];
    > }
    >
    > If I put a breakpoint at the top and step trough this code I do get
    > the file contents in the NSString. However, if I run without
    > breakpoints I get an empty string yet when I inspect /tmp/
    > myFile.tmp via the Terminal, it has the expected content.
    >
    > Is there some file system flushing I need to do?
    >
    > Thanks,
    > Gonzalo
    >
previous month august 2007 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 31    
Go to today