如何使NSOutputStream重定向到标准输出?

Cha*_*pta 9 io cocoa objective-c

我想知道什么是NSOutputStream重定向到标准输出的最佳方法.我现在使用的技术是使用输出流写入内存,获取其数据并将其打印到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];
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来实现这一目标?具体来说,我不满意这种方法的两件事:

  1. 对于写入流的数据需要额外的内存

  2. 此流不可重用 - 在我从此流中检索数据后[stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey],流不会"重置",即我希望后续调用此方法只给我新数据,但事实并非如此.这意味着每次写入stdout后我都必须创建一个新的NSOutputStream.

jtb*_*des 11

它似乎没有内置的方法来做到这一点.如果你可以使用NSFileHandle而不是NSOutputStream,你可以使用[NSFileHandle fileHandleWithStandardOutput].如果你必须使用NSOutputStream,尝试这样的事情:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

现在用

FileHandleOutputStream *myStrem = [FileHandleOutputStream outputStreamWithFileHandle:
                                   [NSFileHandle fileHandleWithStandardOutput]];
Run Code Online (Sandbox Code Playgroud)