我一直在挖掘一個答案很長一段時間,但我從來沒有得到一個工作代碼。NSTask與長輸出(OSX)
我有一個代碼,使用dd來生成一個文件。有時需要幾分鐘時間,具體取決於尺寸,我認爲擁有進度條會很棒。到目前爲止,一切正常,並被捆綁起來。但是,進度條不會更新,因爲我需要不斷向其發送值。我找到了獲取當前值的方法,我設法獲取當前數據,但現在我無法在應用程序中實時獲取輸出結果,除了日誌。
到目前爲止,這是我得到的最好:
// 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次服務器,但沒有成功獲取輸出。我怎樣才能做到這一點?我可以閱讀關於這個主題的任何文件嗎?
謝謝!
不知道這是否是正確的解決方案。但如何在後臺線程中運行您的任務? – Mikael
「pv」做什麼? –
嗨馬丁,光伏是一個管道查看器。請參閱此頁:http://www.catonmat.net/blog/unix-utilities-pipe-viewer/ – Apollo