- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想要完成的是启动命令行(CL)任务(包装的 NSTask)并通过 UI 中的 NSTextField 标签以字符流的形式实时传输字符输出(NSPipe)。文本字段的目的不是以任何方式捕获输出,甚至不允许读取输出。它只是为了显示它,部分作为 UI 装饰,部分作为一种进度指示器。我希望用户在 CL 任务完成工作时看到一串字符(快速)流过。
我知道如何将 CL 任务包装在 NSTask 中,并通过设置 [task setStandardOutput:outputPipe] 获取其输出,然后使用 NSFileHandle 从该输出中读取。我想我知道如何使用 NSFileHandle 读取方法之一以“硬”方式做我想要的事情,并同步将输出切成 block 并在文本字段中一一显示这些 block 。但我希望可能有一些我没有想到的轻量级方法可以将原始 ASCII 字符从标准输出实时发送到文本字段。
有人有想法吗?
编辑:这是一些基于@Peter Hosey 答案的工作代码。它正在做我想做的事情,但我不知道我是否彻底理解了彼得的概念,或者我是否在这里做了任何奇怪的事情,所以请随意发表评论。再次感谢彼得!
此代码的注释:
1) 将 init 中的 ScheduledTimerWithTimeInterval 从 .001 更改为 .005 对于文本滚动效果来说是一个有趣的视觉范围。
2) 我使用的标签只是在界面生成器中的 UI 上创建的简单文本标签。出于我的目的,我不需要使用正确的合理属性字符串来完成彼得答案的第二部分。我只是在界面生成器中设置了文本标签的对齐方式。
@interface MyWrapper : NSObject
@property (assign) NSMutableData *_outputData;
@property (assign) NSFileHandle *_fileHandle;
@property (assign) IBOutlet NSTextField *label;
@property (assign) NSTimer *_timer;
-(void) readData:(NSNotification *)notification;
-(void) displayOutput;
-(void) doIt;
@end
@implementation MyWrapper
@synthesize _outputData, _fileHandle, label, _timer;
- (id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector( readData: )
name:NSFileHandleReadCompletionNotification
object:nil];
_outputData = [[NSMutableData alloc] initWithCapacity:300];
_timer = [NSTimer scheduledTimerWithTimeInterval:.001
target:self
selector:@selector(displayOutput)
userInfo:nil
repeats:YES];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_timer invalidate];
[super dealloc];
}
-(void) readData:(NSNotification *)notification {
if( [notification object] != _fileHandle )
return;
[_outputData appendData:[[notification userInfo]
objectForKey:NSFileHandleNotificationDataItem]];
[_fileHandle readInBackgroundAndNotify];
}
-(void) displayOutput {
if ([_outputData length] == 0) {
return;
}
NSString *labelText = [label stringValue];
NSData *nextByte;
NSString *nextChar;
// pull first character off of the outputData
nextByte = [_outputData subdataWithRange:NSMakeRange(0, 1)];
nextChar = [[NSString alloc]initWithData:nextByte
encoding:NSASCIIStringEncoding];
// get rid of first byte of data
[_outputData replaceBytesInRange:NSMakeRange(0, 1) withBytes:NULL length:0];
if (! [nextChar isEqualToString:@"\n"]) {
if ([labelText length] > 29) {
labelText = [labelText substringFromIndex:1];
}
labelText = [labelText stringByAppendingString:nextChar];
[label setStringValue:labelText];
}
}
-(void)doIt {
NSTask *theTask = [[NSTask alloc] init];
NSPipe *outPipe =[NSPipe pipe];
//write output to outputData in background
_fileHandle = [outPipe fileHandleForReading];
[_fileHandle readInBackgroundAndNotify];
[theTask setLaunchPath:@"path/to/executable"];
[theTask setStandardOutput:outPipe];
[theTask setStandardError:[NSPipe pipe]];
[theTask launch];
[theTask waitUntilExit];
}
@end
最佳答案
Asynchronous reading of the file handle ,一个timer ,一个 NSMutableData,您可以通过仅保留最后一个字节并删除旧字节来将其限制为固定字节数(假设为 300),并在文本字段中右对齐。
对于最后一部分,您需要制作 the default paragraph style 的可变副本, set its alignment至right justification ,并设置文本字段的 attributed string value段落样式为 one of its attributes 的属性字符串.
关于objective-c - NSTask 字符输出到 NSTextField 无缓冲作为连续流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6635086/
我正在使用 MediaPlayer 在我的应用程序中播放在线 mp3 文件中的一些声音。 但是,即使在播放完成后,我也会在控制台中收到一行又一行的回调和缓冲。 10-24 08:08:48.467
我有一个简单的多边形。 dfr p = st_polygon(list(as.matrix(dfr))) > pbuf = st_buffer(p, .4) > plot(pbuf) > plot(
这可能又是一些愚蠢的问题,也许这确实是我所缺少的东西,但我很难让 glMultiDrawArrays 在 OpenGL4 中工作。 我发现了很多这样的解释: for (int i = 0; i #i
这仅仅是根据网络速度调整预缓冲内容量的问题吗?你是否在一开始就为此调整一次,每秒......? 或者它更复杂 - 对您的网络速度记录历史进行采样并取平均值/中值并对其进行调整? 最佳答案 您的第二段总
嗨,我正在使用 FFmpeg Autogen C#。当我使用 mkv 输出作为文件并使用 h264 rtsp 流作为输入时,一切正常。编解码器是 libx264 ffmpeg.avio_open(
我需要多次遍历几个文本文件的行。目前这是通过多个 with open("file.txt") as f: for line in f: # do something 虽然性能还
昨天给同学们写了一个xinetd小练习:做一个反向回显程序。 为了学习新东西,我尝试实现一个 Haskell 解决方案。琐碎的main = forever $ interact reverse不起作用
我正在阅读《实时渲染第三版》中的遮挡剔除部分,但我无法理解它是如何工作的。一些问题: “Z 金字塔”有何贡献?为什么我们需要多种分辨率的 Z 缓冲区?在书中,它的显示如下(左侧): 八叉树结构与用于一
我通过串行端口与设备通信。 我已成功获取 InputStream 并读取设备发送的内容。 但问题是,我根本不知道何时停止阅读并继续执行另一项任务。 这是简化的代码: inputStream = ser
我有以下代码: func (q *Queue) GetStreams(qi *QueueInfo) { channel := make(chan error, len(qi.AudioChun
在我调用 -play 之前,有没有办法让 MPMusicPlayerController 缓冲内容?还是在您设置队列时默认执行此操作? AVAudioPlayer 有 -prepareToPlay 方
我正在编写一个数据库 备份函数,从System.Diagnostics.Process 对象 读取StandardOutput (StreamReader) 属性。我已成功写入普通文件。 //This
我有一个 wpf 应用程序,其中所有 viewModel 都继承自实现 INotifyPropertyChanged 的类 NotifyPropertyChangeClass(见下文)。 我想限制
我需要类似于 withLatestFrom 的东西,对应于下图: ---------A-----------------B-- -1-2-3------4------5-6-7-8---- -----
有没有办法缓冲 OutputStream,在返回之前修改它?这是我的代码片段: public ServletOutputStream getOutputStream() throws IOExcept
目前我们有实现服务器通信协议(protocol)缓冲的需求。如果有人对此有任何意见,他们可以向我提供任何意见吗。 最佳答案 请查看以下 Protocol Buffer 链接。 http://code.
所以我目前正在开发一个 Java 应用程序,该应用程序应该将特定事件记录到数据库中。我希望每分钟最多有 15 到 20 次插入,基本上我想知道我是否应该为每个插入语句建立一个新连接,或者只要应用程序正
请考虑以下代码,包括两个线程 buffering_thread(用一条消息填充缓冲区指针)和 sending_thread(清空缓冲区): #include "msg.cpp" msg * buffe
是否可以在线播放由两个或多个视频文件组成的视频? 由于我原来的帖子不够清楚,这里有扩展的解释和问题。 我的站点托管在 Linux/Apache/PHP 服务器上。我有 FLV/F4V 格式的视频文件。
这是我用于缓冲和转换传入事件的代码: public Publisher> logs(String eventId) { ConnectableObservable connectableObs
我是一名优秀的程序员,十分优秀!