Как заставить NSOutputStream перенаправить на стандартный вывод? - PullRequest
9 голосов
/ 15 августа 2011

Мне было интересно, как лучше всего перенаправить 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. Потребность в дополнительной памяти для данных, записываемых в поток

  2. Этот поток нельзя использовать повторно - после того, как я получил данные из этого потока через [stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey], поток не «сбрасывается», т.е. я хочу, чтобы последующие вызовы этого метода давали мне только новые данные, но не тот случай. Это означает, что мне нужно создавать новый NSOutputStream после каждой записи в stdout.

Ответы [ 2 ]

11 голосов
/ 21 августа 2011

Не похоже, что есть встроенный способ сделать это.Если вы можете использовать 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;
}

Теперь используйте

FileHandleOutputStream *myStrem = [FileHandleOutputStream outputStreamWithFileHandle:
                                   [NSFileHandle fileHandleWithStandardOutput]];
0 голосов
/ 08 сентября 2011

Вы также можете открыть NSOutputStream для stdout, используя "/ dev / tty" в качестве файла. («/ dev / tty» - это обозначение Unix для стандартного ввода и вывода.)

Таким образом, вы можете создать NSOutputStream для стандартизации с:

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

Недостатком является то, что это не будет работать, если вы запустите свою программу в Xcode; вам придется запустить его в окне терминала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...