2015-09-25 105 views
1

我有一個命令運行使用exec()從一個非常大的數據文件中返回一個值,但它必須運行數百萬次。爲了避免每次循環打開文件,我想轉到基於proc_open的解決方案,其中文件指針爲提高效率而創建一次,但無法解決如何執行此操作。如何從使用proc_open打開一次的文件獲得多個結果?

這裏是exec基礎的版本,這工作,但速度很慢,大概是因爲它擁有打開每次迭代的文件:

foreach ($locations as $location) { 
    $command = "gdallocationinfo -valonly -wgs84 datafile.img {$location['lon']} {$location['lat']}"; 
    echo exec ($command); 
} 

我在proc_open基於代碼嘗試如下:

$descriptorspec = array (
    0 => array ('pipe', 'r'), // stdin - pipe that the child will read from 
    1 => array ('pipe', 'w'), // stdout - pipe that the child will write to 
    // 2 => array ('file', '/tmp/errors.txt', 'a'), // stderr - file to write to 
); 

$command = "gdallocationinfo -valonly -wgs84 datafile.img"; 
$fp = proc_open ($command, $descriptorspec, $pipes); 

foreach ($locations as $location) { 
    fwrite ($pipes[0], "{$location['lon']} {$location['lat']}\n"); 
    fclose ($pipes[0]); 
    echo stream_get_contents ($pipes[1]); 
    fclose ($pipes[1]); 
} 

proc_close ($fp); 

這正確地獲取第一值,但隨後爲每個後續迭代產生一個錯誤:

3.3904595375061 

Warning: fwrite(): 6 is not a valid stream resource in file.php on line 11 
Warning: fclose(): 6 is not a valid stream resource in file.php on line 12 
Warning: stream_get_contents(): 7 is not a valid stream resource in file.php on line 13 
Warning: fclose(): 7 is not a valid stream resource in file.php on line 14 

Warning: fwrite(): 6 is not a valid stream resource in file.php on line 11 
... 
+0

似乎'gdallocationinfo'在返回第一個結果後關閉其stdin流。你確定這種類型的使用是由'gdallocationinfo'支持的嗎? – peaceman

回答

0
  1. 您不是「打開文件」,而是執行流程。如果這個過程不是爲了在一次執行的範圍內處理多個請求而設計的,那麼你將無法通過proc_open()或其他任何東西來解決這個問題。
  2. 在下面的塊中,您關閉了進程的輸入和輸出管道,但是當您不再能夠讀取或寫入時,您會感到驚訝嗎?

    foreach ($locations as $location) { 
        fwrite ($pipes[0], "{$location['lon']} {$location['lat']}\n"); 
        fclose ($pipes[0]); // here 
        echo stream_get_contents ($pipes[1]); 
        fclose ($pipes[1]); // and here 
    } 
    

    嘗試這樣做。