【问题标题】:PHP: Receive and store large binary dataPHP:接收和存储大型二进制数据
【发布时间】:2019-06-02 10:10:51
【问题描述】:

我的 PHP 脚本正在从客户端接收大量数据 (100 - 500 MB)。我希望我的 PHP 脚本运行得快,而且不占用太多内存。

为了节省流量,我不使用 Base64 或表单数据。我直接在 POST 请求中发送二进制数据。

数据由两部分组成:2000 字节标头,其余部分必须作为文件存储在服务器上。

$fle = file_get_contents("php://input",FALSE,NULL,2000);
file_put_contents("file.bin", $fle);

问题是file_get_contents忽略了offset参数,从0字节开始读取数据,有没有更好的办法呢?

** 我不想读取整个数据并切掉最后 N-2000 个字节,因为我担心它会占用太多内存。

【问题讨论】:

  • substr($fle, 2000)
  • 首先不要创建另一个变量-$fle-file_put_contents("file.bin", file_get_contents("php://input",FALSE,NULL,2000));
  • @Accountantم 仍然会将所有内容读入内存,然后再将其刷新到磁盘。
  • @Sammitch 是的,我知道,这只会阻止在内存中创建另一个数据副本。顺便说一句,你发布的答案很好,我做了类似的缓冲区before
  • @Accountantم 啊,我看错了你之前的评论。无论有没有变量赋值,它都应该是 1x。

标签: php binary


【解决方案1】:

使用较低级别的文件 IO 函数,一次读/写一点。

$bufsz = 4096;

$fi = fopen("php://input", "rb");
$fo = fopen("file.bin", "wb");

fseek($fi, 2000);

while( $buf = fread($fi, $bufsz) ) {
  fwrite($fo, $buf);
}

fclose($fi);
fclose($fo);

这将读取/写入 4kB 块。

【讨论】:

  • 需要注意的是你的执行时间——确保你已经在你的 php ini 中设置了这个。很好的答案,但有解释!不知道您可以指定要一致读取的大小,始终使用 filesize() 作为第二个参数。很高兴知道以供将来参考。
  • 顺便说一句。有没有一种简单的方法可以从 $fi 读取 N 个字节?就我而言, fread() 通常返回小于第二个参数的值。
  • @IvanKuckir 每个文件最多只能发生 一次,并且仅在文件末尾不是缓冲区大小的偶数倍时才发生。这可以。任何其他观察到的情况都是需要解决的不同问题。
  • @Sammitch 我用 $bufsz = 1000000 运行了你的代码; (这比我的文件大)。该文件已保存,但一次读取的字节数不会超过 8192 个。
  • @IvanKuckir php://input 是一个特殊的流,可能有一些与之相关的特性。除非您出于某种原因有特殊要求在内存中保存约 1MB 的数据,否则 8192 字节或更小的缓冲区大小应该可以正常工作。
猜你喜欢
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多