PHP读取部分大型CSV文件


PHP read part of large CSV file

我有一个很大的CSV文件。由于内存问题(MySQL),如果可能的话,我希望一次只读取其中的一部分。

它是CSV可能并不重要。重要的是,它需要用一个新的行来截断。

示例内容:

Some CSV content
that will break
on a line break

这可能是我的路径:

$path = 'path/to/my.csv';

在我看来,它的解决方案可能是这样的:

$csv_content1 = read_csv_file($path, 0, 100);
$csv_content2 = read_csv_file($path, 101, 200);
  1. 读取第0-100行原始内容。
  2. 读取101-200行的原始内容。

  • 不需要解析(只拆分为内容)。
  • 文件存在于我自己的服务器上。不要把整个文件读到内存中。
  • 我希望能够在另一个时间做第二次读取,而不是在同一运行。如果需要,我接受像指针一样保存临时值。

我一直在尝试阅读其他主题,但没有找到与此问题完全匹配的主题。

也许其中一些可以以某种方式工作?

  • SplFileObject
  • :

也许我不能在使用$csv_content1之前使用$csv_content2,因为我需要保存某种指针?那样的话就好了。我还是按顺序读吧

经过深思熟虑和阅读,我终于认为我找到了解决问题的方法。如果这是一个糟糕的解决方案,因为内存使用或从其他角度,请纠正我。

首次运行

$buffer = part($path_to_file, 0, 100);
下运行

$buffer = part($path_to_file, $buffer['pointer'], 100);

function part($path, $offset, $rows) {
    $buffer = array();
    $buffer['content'] = '';
    $buffer['pointer'] = array();
    $handle = fopen($path, "r");
    fseek($handle, $offset);
    if( $handle ) {
        for( $i = 0; $i < $rows; $i++ ) {
            $buffer['content'] .= fgets($handle);
            $buffer['pointer'] = mb_strlen($buffer['content']);
        }
    }
    fclose($handle);
    return($buffer);
}

在我更面向对象的环境中,它看起来更像这样:

function part() {
    $handle = fopen($this->path, "r");
    fseek($handle, $this->pointer);
    if( $handle ) {
        for( $i = 0; $i < 2; $i++ ) {
            if( $this->pointer != $this->filesize ) {
                $this->content .= fgets($handle);
            }
        }
        $this->pointer += mb_strlen($this->content);
    }
    fclose($handle);
}