php - 分割可变大小块的最节省内存的方法?

标签 php split fread

有没有办法在变量上执行类似 fread 的操作? 也就是说,我想一次“读取”另一个内存变量 1MB。

这样我就可以得到这样的东西:

$data = ... ; // 10MB of data

$handle = fopen($data, "rb"); // Need something instead of fopen here

while (!feof($handle))
{
    $chunk = fread($handle, 1048576); // Want to read 1MB at a time

    doSomethingWithChunk($chunk);
}

fclose($handle);

我有一个很大的二进制文件加载到内存中,大约 10MB。我想将它分成一个 1MB block 的数组。我不需要一次在内存中存储所有 1MB block ,所以我认为我可以比仅仅使用 PHP 的内置 str_split 更有效地执行类似上述的操作。功能。

最佳答案

没有办法顺序“读取”已经加载到内存中的字符串;拆分起来其实并没有效率更高。多个变量的开销也会比单个变量使用更多的内存。理想情况下,您会将字符串加载到流中,但 PHP 并没有真正的字符串流。

如果您只想分块处理字符串,则可以循环遍历它的子字符串:

$data;
$pointer = 0, $size = strlen($data);

$chunkSize = 1048576;
while ($pointer < $size)
{
    $chunk = substr($data, $pointer, $chunkSize);
    doSomethingWithChunk($chunk);
    $pointer += $chunkSize;
}

我不确定 PHP 如何在内部处理大字符串,但根据 string documentation ,字符串只能“最大为 2GB(最大 2147483647 字节)”。如果您的文件大约 10MB,那么对于 PHP 来说应该不成问题。

另一个选项(可能是更好的选项)是将 $data 加载到 memory or temporary stream 中。 。如果您想避免环境内存过多,可以使用 php://temp 流包装器,其中部分数据超过 2MB 时将存储在临时文件中。只需尽快将字符串加载到流中以节省内存,然后就可以在其上使用文件流函数了。

$dataStream = fopen("php://temp", "w+b");
fwrite($dataStream, funcThatGetsData()); // try not to put data into a variable to save memory

while (!feof($dataStream))
{
    $chunk = fread($dataStream, 1048576); // want to read 1MB at a time
    doSomethingWithChunk($chunk);
}

fclose($dataStream);

如果您从另一个函数获取$data,则可以传递$dataStream。如果您必须事先在字符串中包含 $data,请务必对其调用 unset() 以释放内存:

$data = getData(); // string from some other function
$dataStream = fopen("php://temp", "w+b");
fwrite($dataStream, $data);
unset($data); // free 10MB of memory!
...

如果您想将其全部保留在内存中,可以使用 php://memory,但在这种情况下您也可以只使用字符串。

关于php - 分割可变大小块的最节省内存的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21121037/

相关文章:

php - 找不到 CodeIgniter CI_Controller

c# - String.Empty 字符串

Java字符串到数组拆分

PHP 查询还显示 ID 75 的结果

php - 合并 symfony1 和 Symfony2 项目

java - 如何轻松解析字符串中双引号内的所有表达式?

c - 如何打印二进制文件的真实内容

c - 将数据读入 C 中的 float 组

PHP - 在 composer.json 中读取版本号

PHP - 可以将成员函数分配给变量吗?