2010-03-09 51 views
5

嗨:我想将stdout重定向到NSTextView。这也可以用于子流程的输出吗?什么可能是实现这一目标的最佳途径?在可可中将stdout重定向到NSTextView的最佳方式是什么?

编辑: 根据彼得Hosey答案我执行以下。但我没有收到通知。我究竟做错了什么?

NSPipe *pipe = [NSPipe pipe]; 
NSFileHandle *pipeHandle = [pipe fileHandleForWriting]; 
dup2(STDOUT_FILENO, [pipeHandle fileDescriptor]); 
NSFileHandle *fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:pipeHandle]; 
[fileHandle acceptConnectionInBackgroundAndNotify]; 

NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter]; 
[dnc addObserver:self selector:@selector(handleNotification:) name:NSFileHandleConnectionAcceptedNotification object:fileHandle]; 
+0

python与此有什么关系? – Eimantas 2010-03-09 08:52:55

+0

@Eimantas:你说得对,它与问题没有直接关系。其实我正在使用PyObj与Python代码写入** stdout **,我想要显示。我应该删除标签... – Sney 2010-03-09 09:12:52

回答

12

我期待着做同样的事情,并遇到这个职位。在阅读完本文和Apple的文档后,我能够弄明白。我在这里包括我的解决方案。在接口中声明“pipe”和“pipeReadHandle”。在init方法中我包括下面的代码:

pipe = [NSPipe pipe] ; 
pipeReadHandle = [pipe fileHandleForReading] ; 
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout)) ; 

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNotification:) name: NSFileHandleReadCompletionNotification object: pipeReadHandle] ; 
[pipeReadHandle readInBackgroundAndNotify] ; 

的的handleNotification:方法是

[pipeReadHandle readInBackgroundAndNotify] ; 
NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSASCIIStringEncoding] ; 
// Do whatever you want with str 
+0

这对我有很大的帮助。谢谢!我用你的建议,并添加这两个消息,使textView增长和autoscroll使用以下:[myTextView setText:[myTextView.text stringByAppendingString:str]]; [myTextView scrollRangeToVisible:NSMakeRange([myTextView.text length],0)]; – ThinkBonobo 2014-04-06 21:35:51

5

我想标准输出重定向到一个NSTextView。

你自己的stdout?

这是否也适用于子过程的输出?

肯定。

什么可能是实现这一目标的最佳方法?

文件描述符是你的朋友在这里。

创建一个管道(使用NSPipe或pipe(2))和dup2其写入结束到STDOUT_FILENO。调用子进程时,不要设置它们的stdout;他们会继承你的stdout,这是你的管道。 (但是,您可能想要关闭子进程中的读取结束,但我不确定这是否有必要;请尝试并找出结果,如果结果如此,则需要使用forkexec,并关闭它们之间的读取端。)

使用kevent或NSFileHandle异步读取管道读取结尾。当新数据进入时,使用某种编码解释它并将其附加到文本视图的内容。

如果文本视图处于滚动视图中,则应在追加到该滚动视图之前检查滚动位置。如果它最后,你可能会想要追加后跳回到最后。

+0

我编辑了一个非工作实现的问题?任何线索? – Sney 2010-03-09 08:48:35

+0

Snej:你有'dup2'的错误方法。然后你传递一个NSFileHandle指针作为文件描述符来创建一个NSFileHandle。然后你假装写入结束是一个套接字并尝试接受一个连接,尽管既没有从listen(2)返回FD(因为它们是管道而不是套接字)。修复'dup2'调用,不要假装文件句柄指针是文件描述符,也不要试图为任一端创建另一个文件句柄,并尝试从*读取结束* *读取*。 – 2010-03-09 18:32:19

0

对于iOS使用stderr而不是stdout。

NSPipe *pipe = [NSPipe pipe]; 
pipeHandle = [pipe fileHandleForReading]; 
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr)); 

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNotification:) name: NSFileHandleReadCompletionNotification object: pipeHandle] ; 
[pipeHandle readInBackgroundAndNotify] ; 

-(void)handleNotification:(NSNotification *)notification{ 

    [pipeHandle readInBackgroundAndNotify] ; 
    NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSASCIIStringEncoding] ; 

} 
相关问题