I was wondering what's the best way to make NSOutputStream
redirect to standard output. The technique I am using right now is to use an output stream that writes to memory, get its data and print that to stdout:
NSOutputStream *stream = [[NSOutputStream alloc] initToMemory];
[stream open];
// calls to stream's -write:maxLengh:
NSData *data = [stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
printf("%s", [string UTF8String]);
[stream close];
Is there a better way to achieve this? Specifically, I am not happy about two things with this approach:
The need for extra memory for data that is written to stream
This stream is not reusable -- after I have retrieved data from this stream via [stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]
, the stream is not "reset" i.e. I want subsequent calls to this method to give me only new data, but its not the case. This means that I have to create a new NSOutputStream after every time I write to stdout.
It doesn't appear there's a built-in way to do this. If you can use NSFileHandle
instead of NSOutputStream
, you can use [NSFileHandle fileHandleWithStandardOutput]
. If you have to use NSOutputStream
, try something like this:
// untested!
@interface FileHandleOutputStream : NSOutputStream
+ (FileHandleOutputStream *)outputStreamWithFileHandle:(NSFileHandle *)fileHandle;
- (id)initWithFileHandle:(NSFileHandle *)fileHandle;
@end
@implementation FileHandleOutputStream {
NSFileHandle *_fileHandle;
}
+ (FileHandleOutputStream *)outputStreamWithFileHandle:(NSFileHandle *)fileHandle {
return [[[self alloc] initWithFileHandle:fileHandle] autorelease];
}
- (id)initWithFileHandle:(NSFileHandle *)fileHandle {
if (self = [super init]) {
_fileHandle = [fileHandle retain];
}
return self;
}
- (void)dealloc {
[_fileHandle release];
[super dealloc];
}
- (BOOL)hasSpaceAvailable {
return YES;
}
- (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)length {
[_fileHandle writeData:[NSData dataWithBytesNoCopy:buffer
length:length
freeWhenDone:NO]];
return length;
}
Now use
FileHandleOutputStream *myStrem = [FileHandleOutputStream outputStreamWithFileHandle:
[NSFileHandle fileHandleWithStandardOutput]];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With