【问题标题】:file_put_contents and file_get_contents exhaust memory sizefile_put_contents 和 file_get_contents 耗尽内存大小
【发布时间】:2013-02-05 17:10:39
【问题描述】:

我有一些简单的尝试从一个文件写入另一个文件。

$content=file_get_contents("C:\Users\Borut\Desktop\sql_PW1\mm_ads (1).sql");
file_put_contents("C:\Users\Borut\Desktop\sql_PW1\New", $content);

我读取的文件大约80M大,php中的内存限制是128M,但是我得到一个错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 80739522 bytes)

所以即使我尝试分配的内存实际上更小,内存也会耗尽?我可以通过增加内存限制来完成这项工作,但我想知道为什么它不适用于这个限制。

【问题讨论】:

  • 错误消息说您在尝试分配 76.99 兆字节时用尽了可用的 128 兆字节。
  • 如果没有第二行,是否还会出现错误?即错误发生在第一行还是第二行?

标签: php file-get-contents memory-limit


【解决方案1】:

它在tried to allocate xxxx bytes 中显示的数量是超出 PHP 内存限制的数量。这意味着您在尝试分配 额外的 ~80MB 时已经用尽了 128MB。

即使你可以将文件放入内存,当你知道文件会很大时,使用fopen/fread/fwrite/的组合会好很多fclose.

不过,我假设您不仅仅是读取内容并将其写入另一个文件,对吧?因为如果这就是您所需要的,您可以使用copy 函数。

【讨论】:

  • 这里的问题是为什么 128 MB 用完了?
  • 是的,我想做的不仅仅是复制文件,如果文件更小,内存耗尽是很奇怪的。
  • 嗯,是的,那是因为 PHP 为 file_put_contents 中的内容分配了一个写入缓冲区,除了从 file_get_contents 的返回中获取的内存。
  • 这是一个有效的解释,因为没有 file_put_contents 它不会耗尽内存。
【解决方案2】:

要下载大文件而不用完内存,请尝试以下功能:

function custom_put_contents($source_url='',$local_path=''){

    $time_limit = ini_get('max_execution_time');
    $memory_limit = ini_get('memory_limit');

    set_time_limit(0);
    ini_set('memory_limit', '-1');      

    $remote_contents=file_get_contents($source_url);
    $response=file_put_contents($local_path, $remote_contents);

    set_time_limit($time_limit);
    ini_set('memory_limit', $memory_limit); 

    return $response;
}

资源

Allowed memory size of 134217728 bytes exhausted

【讨论】:

    【解决方案3】:

    首先猜测是 file_get_contents() 正在分配 80M 的内存,而 file_put_contents() 正在尝试分配另外 80M。你可以试试把

    var_dump(memory_get_usage())
    

    字里行间。

    请注意,此错误消息并未说明实际使用了多少内存:

    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 80739522 bytes)
    

    所以这可能意味着 PHP 实际上正在使用 100M 并试图分配另外的 80M

    当然,对于这么大的文件,您可以使用 fopen() fwrite() 而不是一次将整个文件放入内存中。

    如果你只是想复制这些文件,你可以简单地使用 copy()

    【讨论】:

      【解决方案4】:

      将整个文件加载到 PHP 中会非常消耗您的内存。如果你需要处理一个对你的内存来说太大的文件,你必须一次加载一点,这意味着你不能使用file_get_contents()

      但是,如果您所做的只是复制文件,则根本不需要加载它——PHP 确实提供了copy() function。工作完成,根本不需要加载。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-25
        • 2011-09-12
        • 1970-01-01
        • 2011-07-12
        • 1970-01-01
        • 2016-10-27
        • 2019-03-17
        • 1970-01-01
        相关资源
        最近更新 更多