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 相关文章推荐
用PHP连接Oracle数据库
Oct 09 PHP
PHP警告Cannot use a scalar value as an array的解决方法
Jan 11 PHP
php存储过程调用实例代码
Feb 03 PHP
wordpress自定义url参数实现路由功能的代码示例
Nov 28 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
Jun 19 PHP
初识PHP
Sep 28 PHP
php使用ZipArchive提示Fatal error: Class ZipArchive not found in的解决方法
Nov 04 PHP
使用PHP生成二维码的方法汇总
Jul 22 PHP
Zend Framework教程之Application用法实例详解
Mar 14 PHP
PHP实现链式操作的原理详解
Sep 16 PHP
php+ajax实现仿百度查询下拉内容功能示例
Oct 20 PHP
基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询操作
Aug 17 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采集速度探究总结(原创)
2008/04/18 PHP
PHP 裁剪图片成固定大小代码方法
2009/09/09 PHP
PHP原生函数一定好吗?
2014/12/08 PHP
php类的扩展和继承用法实例
2015/06/20 PHP
微信公众号模板消息群发php代码示例
2016/12/29 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
document.open() 与 document.write()的区别
2007/08/13 Javascript
基于Jquery+Ajax+Json实现分页显示附效果图
2014/07/30 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
2015/07/15 Javascript
Javascript实现获取及设置光标位置的方法
2015/07/21 Javascript
javascript简易画板开发
2020/04/12 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
node+vue实现用户注册和头像上传的实例代码
2017/07/20 Javascript
Vue项目路由刷新的实现代码
2019/04/17 Javascript
js实现特别简单的钟表效果
2020/09/14 Javascript
JavaScript缓动动画函数的封装方法
2020/11/25 Javascript
[03:14]2014DOTA2西雅图国际邀请赛 EG战队巡礼
2014/07/07 DOTA
python使用pyhook监控键盘并实现切换歌曲的功能
2014/07/18 Python
Python正则表达式完全指南
2017/05/25 Python
python PyTorch预训练示例
2018/02/11 Python
一篇文章读懂Python赋值与拷贝
2018/04/19 Python
如何实现删除numpy.array中的行或列
2018/05/08 Python
pandas.dataframe中根据条件获取元素所在的位置方法(索引)
2018/06/07 Python
Python常用数据类型之间的转换总结
2019/09/06 Python
python通过SSH登陆linux并操作的实现
2019/10/10 Python
在Mac中PyCharm配置python Anaconda环境过程图解
2020/03/11 Python
django queryset 去重 .distinct()说明
2020/05/19 Python
如何一键升级Python所有包
2020/11/05 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
锐步美国官方网站:Reebok美国
2018/01/10 全球购物
如何选择使用结构还是类
2014/05/30 面试题
年会搞笑主持词串词
2014/03/24 职场文书
员工试用期自我鉴定范文
2014/09/15 职场文书
年度考核表个人总结
2015/03/06 职场文书
入党自传范文2015
2015/06/26 职场文书
详解Nginx启动失败的几种错误处理
2021/04/01 Servers