PHP快速按行读取CSV大文件的封装类分享(也适用于其它超大文本文件)


Posted in PHP onApril 10, 2014

CSV大文件的读取已经在前面讲述过了(PHP按行读取、处理较大CSV文件的代码实例),但是如何快速完整的操作大文件仍然还存在一些问题。

1、如何快速获取CSV大文件的总行数?

办法一:直接获取文件内容,使用换行符进行拆分得出总行数,这种办法对小文件可行,处理大文件时不可行;
办法二:使用fgets一行一行遍历,得出总行数,这种办法比办法一好一些,但大文件仍有超时的可能;
办法三:借助SplFileObject类,直接将指针定位到文件末尾,通过SplFileObject::key方法获取总行数,这种办法可行,且高效。

具体实现方法:

$csv_file = 'path/bigfile.csv';
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek(filesize($csv_file));
echo $spl_object->key();

2、如何快速获取CSV大文件的数据?

仍然使用PHP的SplFileObject类,通过seek方法实现快速定位。

$csv_file = 'path/bigfile.csv';
$start = 100000;  // 从第100000行开始读取
$num = 100;    // 读取100行
$data = array();
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek($start);
while ($num-- && !$spl_object->eof()) {
 $data[] = $spl_object->fgetcsv();
 $spl_object->next();
}
print_r($data);

3、综合上面两点,整理成一个csv文件读取的类:

class CsvReader {
 private $csv_file;
 private $spl_object = null;
 private $error; public function __construct($csv_file = '') {
  if($csv_file && file_exists($csv_file)) {
   $this->csv_file = $csv_file;
  }
 }
 public function set_csv_file($csv_file) {
  if(!$csv_file || !file_exists($csv_file)) {
   $this->error = 'File invalid';
   return false;
  }
  $this->csv_file = $csv_file;
  $this->spl_object = null;
 }
 public function get_csv_file() {
  return $this->csv_file;
 }
 private function _file_valid($file = '') {
  $file = $file ? $file : $this->csv_file;
  if(!$file || !file_exists($file)) {
   return false;
  }
  if(!is_readable($file)) {
   return false;
  }
  return true;
 }
 private function _open_file() {
  if(!$this->_file_valid()) {
   $this->error = 'File invalid';
   return false;
  }
  if($this->spl_object == null) {
   $this->spl_object = new SplFileObject($this->csv_file, 'rb');
  }
  return true;
 }

 public function get_data($length = 0, $start = 0) {
  if(!$this->_open_file()) {
   return false;
  }
  $length = $length ? $length : $this->get_lines();
  $start = $start - 1;
  $start = ($start < 0) ? 0 : $start;
  $data = array();
  $this->spl_object->seek($start);
  while ($length-- && !$this->spl_object->eof()) {
   $data[] = $this->spl_object->fgetcsv();
   $this->spl_object->next();
  }
  return $data;
 }
 public function get_lines() {
  if(!$this->_open_file()) {
   return false;
  }
  $this->spl_object->seek(filesize($this->csv_file));
  return $this->spl_object->key();
 }
 public function get_error() {
  return $this->error;
 }
}

调用方法如下:
include('CsvReader.class.php');
$csv_file = 'path/bigfile.csv';
$csvreader = new CsvReader($csv_file);
$line_number = $csvreader->get_lines();
$data = $csvreader->get_data(10);
 
echo $line_number, chr(10);
print_r($data);

其实,上述CsvReader类并不只针对CSV大文件,对于其他文本类型的大文件或超大文件同样可用,前提是将类中fgetcsv方法稍加改动为current即可。

 

 

PHP 相关文章推荐
使用sockets:从新闻组中获取文章(一)
Oct 09 PHP
php heredoc和phpwind的模板技术使用方法小结
Mar 28 PHP
php去除重复字的实现代码
Sep 16 PHP
PHP设计模式之命令模式的深入解析
Jun 13 PHP
win7下memCache的安装过程(具体操作步骤)
Jun 28 PHP
PHP中$_FILES的使用方法及注意事项说明
Feb 14 PHP
PHP中date与gmdate的区别及默认时区设置
May 12 PHP
PHP微信红包生成代码分享
Oct 06 PHP
PHP获取HTTP body内容的方法
Dec 31 PHP
php实现JWT(json web token)鉴权实例详解
Nov 05 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 PHP
TP3.2.3框架文件上传操作实例详解
Jan 23 PHP
php实现批量下载百度云盘文件例子分享
Apr 10 #PHP
PHP图片等比缩放类SimpleImage使用方法和使用实例分享
Apr 10 #PHP
PHP按行读取、处理较大CSV文件的代码实例
Apr 09 #PHP
PHP二维数组排序的3种方法和自定义函数分享
Apr 09 #PHP
php计算几分钟前、几小时前、几天前的几个函数、类分享
Apr 09 #PHP
PHP扩展模块Pecl、Pear以及Perl的区别
Apr 09 #PHP
排序算法之PHP版快速排序、冒泡排序
Apr 09 #PHP
You might like
PHP 柱状图实现代码
2009/12/04 PHP
php缓冲 output_buffering的使用详解
2013/06/13 PHP
PHP自带方法验证邮箱、URL、IP是否合法的函数
2016/12/08 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
(function($){...})(jQuery)的意思
2010/07/22 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
基于jQuery实现点击列表加载更多效果
2016/05/31 Javascript
第一次接触神奇的Bootstrap网格系统
2016/07/27 Javascript
功能强大的Bootstrap使用手册(一)
2016/08/02 Javascript
详解JavaScript的闭包、IIFE、apply、函数与对象
2016/12/21 Javascript
JavaScript中防止微信浏览器被整体拖动的方法
2017/08/25 Javascript
vue实现未登录跳转到登录页面的方法
2018/07/17 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
通过高德地图API获得某条道路上的所有坐标用于描绘道路的方法
2020/08/24 Javascript
Nodejs + sequelize 实现增删改查操作
2020/11/07 NodeJs
python多线程http下载实现示例
2013/12/30 Python
用Python进行基础的函数式编程的教程
2015/03/31 Python
给你选择Python语言实现机器学习算法的三大理由
2017/11/15 Python
python使用xslt提取网页数据的方法
2018/02/23 Python
Python实现简单的用户交互方法详解
2018/09/25 Python
python实现给scatter设置颜色渐变条colorbar的方法
2018/12/13 Python
Python3列表内置方法大全及示例代码小结
2019/05/10 Python
Python局部变量与全局变量区别原理解析
2020/07/14 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
2020/11/19 Python
马来西亚与新加坡长途巴士售票网站:BusOnlineTicket.com
2018/11/05 全球购物
法国亚马逊官方网站:Amazon.fr
2020/12/19 全球购物
如何开启linux的ssh服务
2015/02/14 面试题
五一促销活动总结
2014/07/01 职场文书
企业法人授权委托书
2014/09/25 职场文书
大学军训的体会
2014/11/08 职场文书
离婚协议书的范本
2015/01/27 职场文书
2015年小学总务工作总结
2015/07/21 职场文书
pytorch Dropout过拟合的操作
2021/05/27 Python
Java 数组内置函数toArray详解
2021/06/28 Java/Android
PostgreSQL聚合函数介绍以及分组和排序
2022/04/12 PostgreSQL