我想逐行读取文件,但不完全加载到内存中。

我的文件太大了,无法在内存中打开,如果尝试这样做,我总是会得到内存溢出错误。

文件大小为1gb。


当前回答

你可以使用fgets()函数逐行读取文件:

$handle = fopen("inputfile.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        // process the line read.
    }

    fclose($handle);
}

其他回答

你可以使用fgets()函数逐行读取文件:

$handle = fopen("inputfile.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        // process the line read.
    }

    fclose($handle);
}
if ($file = fopen("file.txt", "r")) {
    while(!feof($file)) {
        $line = fgets($file);
        # do same stuff with the $line
    }
    fclose($file);
}

你可以为文件使用一个面向对象的接口类——SplFileObject http://php.net/manual/en/splfileobject.fgets.php (PHP 5 >= 5.1.0)

<?php

$file = new SplFileObject("file.txt");

// Loop until we reach the end of the file.
while (!$file->eof()) {
    // Echo one line from the file.
    echo $file->fgets();
}

// Unset the file to call __destruct(), closing the file handle.
$file = null;

有一个file()函数返回文件中包含的行数组。

foreach(file('myfile.txt') as $line) {
   echo $line. "\n";
}

如果你想在打开一个大文件时使用foreach而不是while,你可能想在Generator中封装while循环,以避免将整个文件加载到内存中:

/**
 * @return Generator
 */
$fileData = function() {
    $file = fopen(__DIR__ . '/file.txt', 'r');

    if (!$file) {
        return; // die() is a bad practice, better to use return
    }    
    while (($line = fgets($file)) !== false) {
        yield $line;
    }

    fclose($file);
};

像这样使用它:

foreach ($fileData() as $line) {
    // $line contains current line
}

通过这种方式,您可以在foreach()中处理单个文件行。

注意:生成器需要>= PHP 5.5