views:

24

answers:

1

I'm reading NSFileHandleReadCompletionNotification messages from the NSNotificationCenter to receive messages from an NSTask. The problem is that the command line program I'm calling is relatively slow to output lines, and it seems that the NSFileHandleReadCompletionNotification message gets posted relatively infrequently (I guess when the buffer fills up).

Is there another Notification message I can use that would post a notification or every line, or is there a way to make the buffer smaller?

Edit: To be clear, I read that the buffer size is "imited to the buffer size of the underlying operating system" in the NSFileHandle documentation, so, I'm hoping there's some other trick.

A: 

If you read from NSFileHandle by

- (void)readInBackgroundAndNotify

method (right?), and parse data in the NSFileHandleReadCompletionNotification handler - so, the buffer size isn't limited - all "availableData" will be read in the background before you receive the notification, then you call the readInBackgroundAndNotify again to fetch next portion...

However I believe your issue happens due to well known I/O buffering technology.

You should turn buffering Off at the task-command side. Example, if you call a Perl script, just put the line

$|=1;

or

use IO::Handle;
STDOUT->autoflush(1);
STDERR->autoflush(1);

near to the top of the script.

For a C-program - use setvbuf function to set buffer size to zero.

UncleMiF
NSFileHandle doesn't wrap C stdio streams; it wraps file descriptors. `setvbuf` will have no effect. (Even if the file handle is backed by a stream internally, you don't have access to that stream; creating your own stream and setting its buffer mode wouldn't affect that of the file handle's stream.)
Peter Hosey
I'm pretty sure Peter is right. I tried your suggestion (by adding the -u flag to my Python task), and nothing changed.The only thing I've tried that's worked so far is adding a bunch of spaces to the output of the Python script, which seems horribly hacky.
oldpatricka