首页 文章

如何逐行读取大文件

提问于
浏览
392

如何在PHP中逐行读取文件,而不将其完全加载到内存中?

我的文件太大而无法在内存中打开,因此我总是遇到内存耗尽错误 .

文件大小为1 GB .

13 回答

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

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

    $handle = fopen("inputfile.txt", "r");
    if ($handle) {
        while (($line = fgets($handle)) !== false) {
            // process the line read.
        }
    
        fclose($handle);
    } else {
        // error opening the file.
    }
    
  • 33

    您可以为文件使用面向对象的接口类 - 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;
    
  • 24

    如果您要打开一个大文件,您可能希望使用生成器和fgets()来避免将整个文件加载到内存中:

    /**
     * @return Generator
     */
    $fileData = function() {
        $file = fopen(__DIR__ . '/file.txt', 'r');
    
        if (!$file)
            die('file does not exist or cannot be opened');
    
        while (($line = fgets($file)) !== false) {
            yield $line;
        }
    
        fclose($file);
    };
    

    像这样用它:

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

    这样您就可以处理foreach()中的各个文件行 .

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

  • 4

    使用缓冲技术来读取文件 .

    $filename = "test.txt";
    $source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
    while (!feof($source_file)) {
        $buffer = fread($source_file, 4096);  // use a buffer of 4KB
        $buffer = str_replace($old,$new,$buffer);
        ///
    }
    
  • 70

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

    foreach(file('myfile.txt') as $line) {
       echo $line. "\n";
    }
    
  • 595
    foreach (new SplFileObject(__FILE__) as $line) {
        echo $line;
    }
    
  • 4

    小心'while(!feof ... fgets()'的东西,fgets可以得到一个错误(returnfing false)并永远循环而不会到达文件的末尾.codaddict最接近正确但是当你的'while fgets'时循环结束,检查feof;如果不是true,那么你有一个错误 .

  • -7

    这个问题的流行解决方案之一将涉及新行字符的问题 . 使用简单的 str_replace 可以很容易地修复它 .

    $handle = fopen("some_file.txt", "r");
    if ($handle) {
        while (($line = fgets($handle)) !== false) {
            $line = str_replace("\n", "", $line);
        }
        fclose($handle);
    }
    
  • 27

    这是我如何管理非常大的文件(测试高达100G) . 它比fgets()更快

    $block =1024*1024;//1MB or counld be any higher than HDD block_size*2
    if ($fh = fopen("file.txt", "r")) { 
        $left='';
        while (!feof($fh)) {// read the file
           $temp = fread($fh, $block);  
           $fgetslines = explode("\n",$temp);
           $fgetslines[0]=$left.$fgetslines[0];
           if(!feof($fh) )$left = array_pop($lines);           
           foreach ($fgetslines as $k => $line) {
               //do smth with $line
            }
         }
    }
    fclose($fh);
    
  • 5

    所有答复都没有明显的答案 . PHP有一个整洁的流分隔符解析器,可用于此目的 .

    $fp=fopen("/path/to/the/file", "r+");
    while ($line = stream_get_line($fp, 1024 * 1024, "\n"))
    {
    echo $line;
    }
    fclose($fp);
    
  • 111

    在处理大型文件时,SplFileObject非常有用 .

    function parse_file($filename)
    {
        try {
            $file = new SplFileObject($filename);
        } catch (LogicException $exception) {
            die('SplFileObject : '.$exception->getMessage());
        }
        while ($file->valid()) {
            $line = $file->fgets();
            //do something with $line
        }
    
        //don't forget to free the file handle.
        $file = null;
    }
    
  • 2

    函数读取数组返回

    function read_file($filename = ''){
        $buffer = array();
        $source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
        while (!feof($source_file)) {
            $buffer[] = fread($source_file, 4096);  // use a buffer of 4KB
        }
        return $buffer;
    }
    

相关问题