[英]How to make NSOutputStream redirect to standard output?
I was wondering what's the best way to make NSOutputStream
redirect to standard output.我想知道将
NSOutputStream
重定向到标准 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:我现在使用的技术是使用 output stream 写入 memory,获取其数据并将其打印到标准输出:
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写入 stream 的数据需要额外的 memory
This stream is not reusable -- after I have retrieved data from this stream via [stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]
, the stream is not "reset" ie I want subsequent calls to this method to give me only new data, but its not the case. This stream is not reusable -- after I have retrieved data from this stream via
[stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]
, the stream is not "reset" ie 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.这意味着我每次写入标准输出后都必须创建一个新的 NSOutputStream。
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]
.如果您可以使用
NSFileHandle
而不是NSOutputStream
,则可以使用[NSFileHandle fileHandleWithStandardOutput]
。 If you have to use NSOutputStream
, try something like this:如果您必须使用
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;
}
Now use现在使用
FileHandleOutputStream *myStrem = [FileHandleOutputStream outputStreamWithFileHandle:
[NSFileHandle fileHandleWithStandardOutput]];
Jason Sikes had it almost correct. Jason Sikes几乎是正确的。
There's no need for Cocoa to provide its own constructor here because stdout is available as a "file." Cocoa 无需在此处提供自己的构造函数,因为标准输出可作为“文件”使用。 This doesn't seem to be documented, unfortunately, but works very well:
不幸的是,这似乎没有记录在案,但效果很好:
NSOutputStream *outputStream =
[NSOutputStream outputStreamToFileAtPath:@"/dev/stdout"
append:NO];
You can do the same thing with stderr as well (or use a NSInputStream for stdin).您也可以使用 stderr 做同样的事情(或使用NSInputStream作为标准输入)。
You can also open a NSOutputStream to stdout using "/dev/tty" as the file.您还可以使用“/dev/tty”作为文件打开一个 NSOutputStream 到标准输出。 ("/dev/tty" is the Unix designation for standard input and output.)
(“/dev/tty”是标准输入和 output 的 Unix 名称。)
Thus you can create a NSOutputStream to standard out with:因此,您可以创建一个 NSOutputStream 以标准输出:
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath: @"/dev/tty"
append: NO];
A drawback is that this won't work if you run your program within Xcode;一个缺点是,如果您在 Xcode 中运行程序,这将不起作用; you'll have to run it in a terminal window.
您必须在终端 window 中运行它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.