9

我正在尝试解析大小约为 1GB 的制表符分隔文件。

我在哪里运行我得到的脚本:

Fatal error: Allowed memory size of 1895825408 bytes exhausted  (tried to allocate 1029206974 bytes) ...

我目前的脚本只是:

$file = file_get_contents('allCountries.txt') ;

$file = str_replace(array("\r\n", "\t"), array("[NEW*LINE]", "[tAbul*Ator]"), $file) ;

我已将 php.ini 中的内存限制设置为 -1,然后给我:

Fatal error: Out of memory (allocated 1029963776) (tried to allocate 1029206974 bytes)

无论如何要部分打开文件然后继续下一部分,以便一次使用更少的内存?

4

4 回答 4

13

是的,您可以逐行阅读:

$handle = @fopen("/tmp/inputfile.txt", "r");
if ($handle) {
    while (($buffer = fgets($handle, 4096)) !== false) {
        echo $buffer;
    }
    fclose($handle);
}
于 2013-02-13T08:04:18.013 回答
2

您必须使用块来读取文件。检查这个问题的答案。 https://stackoverflow.com/a/6564818/1572528

您也可以尝试将其用于较小的文件。

ini_set('memory_limit', '32M'); //max size 32m
于 2013-02-13T08:07:43.207 回答
1

您确定这fopen是失败而不是脚本的超时设置吗?默认值通常约为 30 秒左右,如果您的文件读取时间比读取时间长,则可能会导致问题。

要考虑的另一件事可能是脚本的内存限制 - 将文件读入数组可能会超出此限制,因此请检查错误日志以获取内存警告。

如果以上都不是您的问题,您可能会考虑使用fgets逐行读取文件,随时处理。

$handle = fopen("/tmp/uploadfile.txt", "r") or die("Couldn't get handle");
if ($handle) {
    while (!feof($handle)) {
        $buffer = fgets($handle, 4096);
        // Process buffer here..
    }
    fclose($handle);
}

编辑

PHP似乎没有抛出错误,它只是返回false。

更正的路径$rawfile是否相对于脚本运行的位置?也许尝试在此处为文件名设置绝对路径。

于 2013-02-13T08:06:13.770 回答
1

是的,为此使用 fopen 和 fread / fgets:

http://www.php.net/manual/en/function.fread.php

string fread ( resource $handle , int $length )

将 $length 设置为要读取的文件数量。然后 $handle 保存新读取的位置,使用 fseek 您还可以稍后设置位置....

于 2013-02-13T08:07:55.513 回答