这是简单的PHP脚本:
<?php
is_resource($process = proc_open('aria2c http://speedtest.rinet.ru/file100m.dat', [
['pipe', 'r'],
['pipe', 'w'],
['file', '/tmp/error-output.txt', 'a']
], $pipes, '/tmp', [])) || die();
fclose($pipes[0]);
fpassthru($pipes[1]);
fclose($pipes[1]);
proc_close($process);
问题是输出中的进度数据"停止",直到aria2c完成。当aria2c进程结束时,它会立即将所有输出突发到我的脚本中。它与 fpassthru() 无关,我已经尝试了普通的 fread() 以获得相同的结果。
流程:
[注意] 文件已存在。重命名为/tmp/file100m.dat.4。
<...巨大的延迟,然后突发...>
[#edb1dc 70MiB/100MiB(70%) CN:1 DL:8.4MiB ETA:3s]
[#edb1dc 81MiB/100MiB(81%) CN:1 DL:9.7MiB ETA:1s]
[#edb1dc 92MiB/100MiB(92%) 中国:1 DL:10MiB]
我需要得到像"[#edb1dc 92MiB/100MiB(92%) CN:1 DL:10MiB]"这样的行,而不必等待aria2c结束来收集有关当前进度的信息。
更不用说,如果我在控制台中运行完全相同的命令 aria2c 工作正常.
我在尝试从 PHP 监控 Aria2 下载进度(读出)时遇到了同样的问题。
该问题是由 Aria2 代码中缺少fflush(stdout)
引起的,但幸运的是,您可以在 PHP 代码中使用修复程序来重新配置 STDOUT 缓冲模式。您可以使用 Linux 下的stdbuf
实用程序或 OSX 下的unbuffer
实用程序来禁用缓冲,如下所示:
proc_open('stdbuf -o0 aria2c ...'); // on Linux
或:
proc_open('unbuffer aria2c ...'); // on OSX
(感谢@hek2mgl对另一个类似问题的回答)