在 PHP 中将大文件写入磁盘的最佳方法是啥?
Posted
技术标签:
【中文标题】在 PHP 中将大文件写入磁盘的最佳方法是啥?【英文标题】:What is the best way to write a large file to disk in PHP?在 PHP 中将大文件写入磁盘的最佳方法是什么? 【发布时间】:2011-06-15 10:38:55 【问题描述】:我有一个偶尔需要将大文件写入磁盘的 php 脚本。使用file_put_contents()
,如果文件足够大(在本例中约为 2 MB),PHP 脚本会耗尽内存(PHP 致命错误:允许的内存大小为 ######## 字节已用尽)。我知道我可以只增加内存限制,但这对我来说似乎不是一个完整的解决方案——必须有更好的方法,对吧?
用 PHP 将大文件写入磁盘的最佳方法是什么?
【问题讨论】:
数据的来源是什么?此外,大多数 PHP 配置应该能够毫无问题地处理 2MB。您的内存限制可能远低于此限制。 文件从何而来?如果它已经存在于磁盘上,那么copy()
将是最合适的。
在这种情况下,我使用 curl 从远程服务器获取文件。所以,我把它放在一个变量中。
跳过 curl,使用copy("http://example.com/file", "/tmp/local.txt")
@mario:这很容易,但我正在复制多个文件,我喜欢我可以使用 curl_multi_* 东西同时运行它们
【参考方案1】:
您需要一个临时文件,在其中放置源文件的部分内容以及要附加的内容:
$sp = fopen('source', 'r');
$op = fopen('tempfile', 'w');
while (!feof($sp))
$buffer = fread($sp, 512); // use a buffer of 512 bytes
fwrite($op, $buffer);
// append new data
fwrite($op, $new_data);
// close handles
fclose($op);
fclose($sp);
// make temporary file the new source
rename('tempfile', 'source');
这样,source
的全部内容不会被读入内存。使用 cURL 时,您可以省略设置 CURLOPT_RETURNTRANSFER
,而是添加一个写入临时文件的输出缓冲区:
function write_temp($buffer)
global $handle;
fwrite($handle, $buffer);
return ''; // return EMPTY string, so nothing's internally buffered
$handle = fopen('tempfile', 'w');
ob_start('write_temp');
$curl_handle = curl_init('http://example.com/');
curl_setopt($curl_handle, CURLOPT_BUFFERSIZE, 512);
curl_exec($curl_handle);
ob_end_clean();
fclose($handle);
似乎我总是错过显而易见的事情。正如 Marc 所指出的,有CURLOPT_FILE
可以直接将响应写入磁盘。
【讨论】:
有道理,但在这种情况下,我使用 curl 从不同的服务器检索文件,因此它已经在内存中。 @Joe 我更新了答案。另一个建议来了。 第一个解决方案你可能也用过stream_copy_to_stream
;-)
@user576875 不。为什么要轻松? :-) 开玩笑。感谢您的提示。
不需要缓冲。 curl 可以使用curl_setopt('CURLOPT_FILE', ...)
直接写入文件【参考方案2】:
使用fwrite()
等函数逐行写入(或在二进制文件的情况下逐包写入)
【讨论】:
【参考方案3】:试试this answer:
$file = fopen("file.json", "w");
$pieces = str_split($content, 1024 * 4);
foreach ($pieces as $piece)
fwrite($file, $piece, strlen($piece));
fclose($file);
【讨论】:
以上是关于在 PHP 中将大文件写入磁盘的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章