【问题标题】:Read File to specific line php将文件读取到特定行 php
【发布时间】:2014-10-12 13:44:05
【问题描述】:

我正在尝试读取一个大文件(大约 500 万行),它一直达到内存限制。有没有办法我可以将文件读取到特定行,然后增加一个计数器并从下一行继续?

这是我正在使用的代码,如何为 fget 添加指向起始行的指针?

$handle = @fopen("large_file.txt", "r");
if($handle){
   while(($buffer = fgets($handle, 4096)) !== false){
      //get the content of the line
    }
}

我不想只阅读一个特定的行,我想从第 1 行读取到第 10,000 行,然后从第 10,001 行重新开始到另外 10,000 行,就像这样。

【问题讨论】:

    标签: php fgets


    【解决方案1】:

    尝试使用此功能,您应该使用迭代并逐行获取。

    $file = new SplFileObject('yourfile.txt');
    
    echo getLineRange(1,10000);
    
    function getLineRange($start,$end){
       $tmp = "";
    
       for ($i = $start; $i <= $end; $i++) {
        $tmp .= $file->seek($i);
       }
       return($tmp);
    }
    

    【讨论】:

    • 请不要发布 2 个答案(而是编辑您的原始答案)。
    【解决方案2】:

    我想答案会在这里Reading specific line of a file in php

    你可以使用 seek 来获取特定的行位置

    $file = new SplFileObject('yourfile.txt');
    $file->seek(123); // seek to line 124 (0-based)
    

    【讨论】:

    • 我不想只读一个特定的行,我想从第一行读到第 10,000 行,然后从第 10,001 行重新开始到另外 10,000 行,就像这样。跨度>
    【解决方案3】:

    可以在 PHP 中使用 fseek()/ftell() 批量处理大文件,并保存块之间的上下文。 (SplFileObject::seek()可以直接逐行查找,但好像有performance issues with large files。)

    假设您有某种可用的批处理器,下面的示例应该让您了解该方法。它未经测试,但源自生产中的代码。

    <?php
    
    $context = array(
        'path' => 'path/to/file',
        'limit' => 1000,
        'line' => NULL,
        'position' => NULL,
        'size' => NULL,
        'percentage' => 0,
        'complete' => FALSE,
        'error' => FALSE,
        'message' => NULL,
    );
    
    function do_chunk($context) {
        $handle = fopen($context['path'], 'r');
        if (!$handle) {
            $context['error'] = TRUE;
            $context['message'] = 'Cannot open file for reading: ' . $context['path'];
            return;
        }
        // One-time initialization of file parameters.
        if (!isset($context['size'])) {
            $fstat = fstat($handle);
            $context['size'] = $fstat['size'];
            $context['position'] = 0;
            $context['line'] = 0;
        }
        // Seek to position for current chunk.
        $ret = fseek($handle, $context['position']);
        if ($ret === -1) {
            $context['error'] = TRUE;
            $context['message'] = 'Cannot seek to ' . $context['position'];
            fclose($handle);
            return;
        }
    
        $k = 1;
        do {
            $context['line']++;
            $raw_line = fgets($handle);
            if ($raw_line) {
                // Strip newline.
                $line = rtrim($raw_line);
                // Code to process line here.
                list($error, $message) = my_process_line($context, $line);
                if ($error) {
                    $context['error'] = TRUE;
                    $context['message'] = $message;
                    fclose($handle);
                    return;
                }
            } elseif (($raw_line === FALSE) && !feof($handle)) {
                $context['error'] = TRUE;
                $context['message'] = 'Unexpected error reading ' . $context['path'];
                fclose($handle);
                return;
            }
        }
        while ($k++ < $context['limit'] && $raw_line);
    
        // Save position of next chunk.
        $position = ftell($handle);
        if ($position !== FALSE) {
            $context['position'] = $position;
        } else {
            $context['error'] = TRUE;
            $context['message'] = 'Cannot retrieve file pointer in ' . $context['path'];
            fclose($handle);
            return;
        }
    
        if (!$raw_line) {
            $context['complete'] = TRUE;
            $context['percentage'] = 1;
        } else {
            $context['percentage'] = $context['position'] / $context['size'];
        }
    
        fclose($handle);
    }
    
    
    // Batch driver for testing only - use a batch processor in production.
    while ($context['complete']) {
        do_batch($context);
    }
    if ($context['error']) {
        print 'error: ' . $context['message'];
    } else {
        print 'complete';
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多