2015-09-25 4 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 
    } 
    

    Попробуйте не делать.