【问题标题】:How do I get multiple results from a file opened only once using proc_open?如何从使用 proc_open 仅打开一次的文件中获取多个结果?
【发布时间】:2015-09-25 18:52:53
【问题描述】:

我有一个使用 exec() 运行的命令,它从一个非常大的数据文件中返回一个值,但它必须运行数百万次。为了避免每次循环打开文件,我想转向基于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
...

【问题讨论】:

  • 似乎gdallocationinfo 在返回第一个结果后关闭其stdin 流。你确定gdallocationinfo支持这种类型的使用吗?

标签: php proc-open


【解决方案1】:
  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
    }
    

    尝试不要那样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-22
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多