【发布时间】:2013-05-30 14:49:29
【问题描述】:
我一直在寻找答案很长时间,但我从来没有得到一个有效的代码。
我有一个使用 dd 生成文件的代码。有时需要几分钟,具体取决于大小,我认为有一个进度条会很棒。到目前为止,一切正常并已绑定。但是,进度条不会更新,因为我需要不断地向它发送值。我找到了一种获取当前值的方法,我设法让 pv 显示当前数据,但现在我无法在应用程序内部实时获取输出,除了在日志中。
到目前为止,这是我能做到的最好的:
// Action:
// dd if=/dev/zero bs=1048576 count=500 |pv -Wn -s <size>|of=/Users/me/Desktop/asd.img
// Be careful, it generates files of 500MB!!
NSTask * d1Task = [[NSTask alloc] init];
NSTask * pvTask = [[NSTask alloc] init];
NSTask * d2Task = [[NSTask alloc] init];
[d1Task setLaunchPath:@"/bin/dd"];
[pvTask setLaunchPath:@"/Users/me/Desktop/pv"];
[d2Task setLaunchPath:@"/bin/dd"];
// For pvTask I use something like...
// [[NSBundle mainBundle] pathForAuxiliaryExecutable: @"pv"]
// ... in the final version.
[d1Task setArguments: [NSArray arrayWithObjects:
@"if=/dev/zero"
, @"bs=1048576"
, @"count=500"
, nil]];
[pvTask setArguments:[NSArray arrayWithObjects:
@"-Wn"
, [ NSString stringWithFormat:@"-s %d", 1048576 * 500]
, nil]];
[d2Task setArguments: [NSArray arrayWithObjects:
@"of=/Users/me/Desktop/file.dmg"
, nil]];
NSPipe * pipeBetween1 = [NSPipe pipe];
[d1Task setStandardOutput: pipeBetween1];
[pvTask setStandardInput: pipeBetween1];
NSPipe * pipeBetween2 = [NSPipe pipe];
[pvTask setStandardOutput: pipeBetween2];
[d2Task setStandardInput: pipeBetween2];
// Missing code here
[d1Task launch];
[pvTask launch];
[d2Task launch];
在缺少的代码部分,我尝试了几件事。首先我尝试了一个观察者,像这样:
NSFileHandle * pvOutput = [pipeBetween2 fileHandleForReading];
[pvOutput readInBackgroundAndNotify];
[ [NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(outputData:)
name:NSFileHandleDataAvailableNotification
object:pvOutput
];
没有成功。我只在执行开始或结束时收到反馈,但在执行过程中仍然没有反馈。
我也尝试过类似的方法:
[pvOutput setReadabilityHandler:^(NSFileHandle *file) {
// Stuff here
}];
但是这里没有这样的方法。也许我的 XCode 已经过时了? (我用的是 4.2)。
最近我一直在尝试使用 /sbin/ping ping 服务器 10 次相同的通用代码,但没有成功获得输出。我怎样才能做到这一点?我可以阅读有关此主题的任何文件吗?
谢谢!
【问题讨论】:
-
不确定这是否是正确的解决方案。但是在后台线程中运行你的任务怎么样?
-
嗨 Martin,pv 是一个管道查看器。请参考本页:catonmat.net/blog/unix-utilities-pipe-viewer
-
嗨 Mikael,我也尝试使用 Grand Central Dispatch。我的原始代码使用 GCD。这是一个辅助项目,用于测试观察者或任何其他从 dd 和 pv 获取反馈的方法。
-
dd所做的只是复制数据。你可以在没有NSTask的情况下自己做得更好,并且你可以完全访问进度而无需进行黑客攻击。 -
嗨 trojanfoe,我有这个代码是因为之前的问题我不得不生成大的空白文件而没有内存问题.. 你可以检查我之前做的一个与此相关的问题 这里:stackoverflow.com/questions/8874757/…
标签: objective-c macos cocoa xcode4.2