2011-08-15 16 views
9

NSOutputStreamを標準出力にリダイレクトする最良の方法は何ですか?これを達成するためのより良い方法がNSOutputStreamを標準出力にリダイレクトする方法は?

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]; 

あります:私が今使っている技術は、メモリへの書き込みを行う出力ストリームを使用してデータを取得し、その標準出力に印刷しているのですか?具体的には、私はこのアプローチには二つのことについて満足していない:

  1. このストリームストリームに書き込まれたデータのための余分なメモリの必要性が再利用可能ではありません - 私はからデータを取得した後、このストリームは[stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]経由で、ストリームは「リセット」されません。つまり、このメソッドへの後続の呼び出しで、私に新しいデータのみを渡しますが、そうではありません。つまり、stdoutに書き込むたびに新しいNSOutputStreamを作成する必要があります。

答えて

11

これを行うための組み込みの方法はありません。 NSOutputStreamの代わりにNSFileHandleを使用できる場合は、[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; 
} 

FileHandleOutputStream *myStrem = [FileHandleOutputStream outputStreamWithFileHandle: 
            [NSFileHandle fileHandleWithStandardOutput]]; 
+0

私は 'NSFileHandle'について知っていましたが、' NSOutputStream'のサブクラスの中にそれをラップすることは、私が考えたものではありません。非常に興味深い、それは確かに動作するはずです。 –

+0

私はこれが正しく動作することを確認したらすぐにあなたの答えを受け入れます(私はこれでも間違っているはずの何も見ません)。 –

+0

これはとてもうまく動作します。私が追加できる唯一の注意点は、 'NSOutputStream'のメソッドをオーバーライドするだけでなく、' -open'や '-close'のようないくつかのNSStreamメソッドをオーバーライドする必要があるかもしれません。助けてくれてありがとう。 –

-1

を使用また、ファイルとして "は/ dev/ttyの" を使用してstdoutにNSOutputStreamを開くことができます。 (。「は/ dev/ttyのは、」標準入力と出力のためのUnixの呼称である)

このようにあなたが標準出力にNSOutputStreamを作成することができます。欠点は、これがあれば動作しませんということです

NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath: @"/dev/tty" 
                  append: NO]; 

あなたはXcodeの中でプログラムを実行します。それをターミナルウィンドウで実行する必要があります。

+1

'/ dev/tty'はプロセスの制御端末であり、標準出力や入力ではありません。これは、例えば、stdoutをファイルにリダイレクトすると失敗します。この場合、 'dev/tty'は端末に出力を表示しますが、これは間違っています。 –

関連する問題