gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 21:10:26 25 4
gpt4 key购买 nike

有没有一种方法可以像 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com