有没有办法像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块的数组。我一次不需要内存中的所有1MB块,所以我认为我可以比使用PHP的内置str_split函数更有效地执行上述操作。
答案 0 :(得分:1)
你可以使用like;
$handle = @fopen("path_to_your_file", "r");
if ($handle) {
while (($buffer = fgets($handle, 1024)) !== false) {
doSomethingWithChunk($buffer );
}
fclose($handle);
}
答案 1 :(得分:1)
没有办法顺序“读取”已经加载到内存中的字符串;拆分它并不是更有效率。多个变量的开销将使用比单个变量更多的内存。理想情况下,您将字符串加载到流中,但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
,但在这种情况下你也可以使用一个字符串。