2013-01-18 26 views
0

我發現從API之一下面的代碼,我想用它做vm_stat 1的實時監控:爲什麼waitForDataInBackgroundAndNotify不支持超過1個參數的實時監控器?

BOOL terminated = NO; 

-(void)realTimeMonitor 
{ 

NSTask *task = [[NSTask alloc] init]; 
[task setLaunchPath:@"/bin/bash"]; 
[task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1", nil]]; //works fine 

// [task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1 | /usr/bin/awk '{print $1}'", nil]]; not working 

NSPipe *pipe = [NSPipe pipe]; 
NSPipe *errorPipe = [NSPipe pipe]; 
[task setStandardOutput:pipe]; 
[task setStandardError:errorPipe]; 

NSFileHandle *outFile = [pipe fileHandleForReading]; 
NSFileHandle *errFile = [errorPipe fileHandleForReading]; 


[task launch]; 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(terminated:) 
              name:NSTaskDidTerminateNotification 
              object:task]; 

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(outData:) 
              name:NSFileHandleDataAvailableNotification 
              object:outFile]; 

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(errData:) 
              name:NSFileHandleDataAvailableNotification 
              object:errFile]; 


[outFile waitForDataInBackgroundAndNotify]; 
[errFile waitForDataInBackgroundAndNotify]; 
while(!terminated) 
{ 
    if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) 
    { 
     break; 
    } 
} 
} 

-(void) outData: (NSNotification *) notification 
{ 
NSFileHandle *fileHandle = (NSFileHandle*) [notification object]; 
NSData *data = [fileHandle availableData]; 

if ([data length]) { 

    NSString *currentString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    // do something 
} 

[fileHandle waitForDataInBackgroundAndNotify]; //Checks to see if data is available in a background thread. 
} 


-(void) errData: (NSNotification *) notification 
{ 
NSLog(@"errData"); 
NSFileHandle *fileHandle = (NSFileHandle*) [notification object]; 
[fileHandle waitForDataInBackgroundAndNotify]; 
} 

- (void) terminated: (NSNotification *)notification 
{ 
NSLog(@"Task terminated"); 
[[NSNotificationCenter defaultCenter] removeObserver:self]; 
terminated =YES; 
} 

========

請查看setArguments行。第一個工作完全正常「/ usr/bin/vm_stat 1」,但第二行不起作用「/ usr/bin/vm_stat 1 |/usr/bin/awk'{print $ 1}'」(no output at所有),但如果我在終端上運行它,它工作得很好。這是爲什麼?

回答

0

也許awk正在緩衝它的標準輸出流,因爲它認爲它不會將其標準輸出流寫入到一個tty設備。

這可能最終會導致一個完整的僵局,因爲它可能爲vm_stat成爲不可能的,如果awk的標準輸入被填滿並沒有對awk沒有消費者的標準輸出寫到標準輸出。

因此請嘗試使用其內置的fflush()函數沖洗awk的stdout。

[task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1 | /usr/bin/awk '{print $1; fflush();}'", nil]]; 

我能夠使用(稍作修改)asynctask.m運行您的代碼。

相關問題