用于在PHP中读取文件的最少内存密集型方法

Che*_*tan 12 php file

我正在使用Php中的file()函数读取包含大约50k行的文件.但是,由于文件内容作为数组存储在内存中,因此会发出内存不足错误.还有其他方法吗?

而且,存储的行的长度是可变的.

这是代码.该文件也是700kB而不是mB.

private static function readScoreFile($scoreFile)
{
    $file = file($scoreFile);
    $relations = array();

    for($i = 1; $i < count($file); $i++)
    {
        $relation = explode("\t",trim($file[$i]));
        $relation = array(
                        'pwId_1' => $relation[0],
                        'pwId_2' => $relation[1],
                        'score' => $relation[2],
                        );
        if($relation['score'] > 0)
        {
            $relations[] = $relation;
        }
    }

    unset($file);
    return $relations;
}
Run Code Online (Sandbox Code Playgroud)

Gum*_*mbo 13

使用fopen,fread并按fclose顺序读取文件:

$handle = fopen($filename, 'r');
if ($handle) {
    while (!feof($handle)) {
        echo fread($handle, 8192);
    }
    fclose($handle);
}
Run Code Online (Sandbox Code Playgroud)

  • 用"fgets"替换fread:fgets - 从文件指针获取行 (7认同)

Gor*_*don 9

在更新问题和评论编辑回复fabjoa:

如果一个700kb的文件使用你提供的代码消耗140MB的内存,那肯定有些可疑(unset尽管你可以在每次迭代结束时使用$ relation).考虑使用调试器逐步执行它以查看会发生什么.您可能还想考虑重写代码以使用SplFileObject的CSV函数(或它们的程序表兄弟)

SplFileObject :: setCsvControl示例

$file = new SplFileObject("data.csv");
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl('|');
foreach ($file as $row) {
    list ($fruit, $quantity) = $row;
    // Do something with values
}
Run Code Online (Sandbox Code Playgroud)

对于迭代文件的OOP方法,请尝试SplFileObject:

SplFileObject :: fgets示例

$file = new SplFileObject("file.txt");
while (!$file->eof()) {
    echo $file->fgets();
}
Run Code Online (Sandbox Code Playgroud)

SplFileObject ::下一个例子

// Read through file line by line
$file = new SplFileObject("misc.txt");
while (!$file->eof()) {
    echo $file->current();
    $file->next();
}
Run Code Online (Sandbox Code Playgroud)

甚至

foreach(new SplFileObject("misc.txt") as $line) {
    echo $line;
}
Run Code Online (Sandbox Code Playgroud)

几乎相关(如果不重复):