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正则
Jul 07 PHP
php+javascript的日历控件
Nov 19 PHP
30 个很棒的PHP开源CMS内容管理系统小结
Oct 14 PHP
php缓冲 output_buffering的使用详解
Jun 13 PHP
zf框架的数据库追踪器使用示例
Mar 13 PHP
php socket实现的聊天室代码分享
Aug 16 PHP
PHP常用技术文之文件操作和目录操作总结
Sep 27 PHP
PHP过滤黑名单关键字的方法
Dec 01 PHP
php实现简易聊天室应用代码
Sep 23 PHP
php 无限级分类 获取顶级分类ID
Mar 13 PHP
PHP chop()函数讲解
Feb 11 PHP
php的无刷新操作实现方法分析
Feb 28 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设置图片文件上传大小的具体实现方法
2013/10/11 PHP
PHP使用redis位图bitMap 实现签到功能
2019/10/08 PHP
实用的JS正则表达式(手机号码/IP正则/邮编正则/电话等)
2013/01/11 Javascript
jquery时间下拉框小例子
2013/04/15 Javascript
JavaScript Promise启示录
2014/08/12 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
快速学习jQuery插件 Form表单插件使用方法
2015/12/01 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
2016/02/25 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
js模拟微博发布消息
2017/02/23 Javascript
基于JavaScript实现的希尔排序算法分析
2017/04/14 Javascript
JS实现无缝循环marquee滚动效果
2017/05/22 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
vue项目中vue-i18n和element-ui国际化开发实现过程
2018/04/25 Javascript
Javasript设计模式之链式调用详解
2018/04/26 Javascript
通过一次报错详细谈谈Point事件
2018/05/17 Javascript
vue el-upload上传文件的示例代码
2020/12/21 Vue.js
[03:01]2014DOTA2国际邀请赛 小组赛7月13日TOPPLAY
2014/07/14 DOTA
[06:44]2014DOTA2国际邀请赛-钥匙体育馆开战 开幕式振奋人心
2014/07/19 DOTA
Python的print用法示例
2014/02/11 Python
Python中使用bidict模块双向字典结构的奇技淫巧
2016/07/12 Python
TensorFlow平台下Python实现神经网络
2018/03/10 Python
python pygame实现2048游戏
2018/11/20 Python
Python matplotlib以日期为x轴作图代码实例
2019/11/22 Python
基于python生成英文版词云图代码实例
2020/05/16 Python
Jupyter Notebook添加代码自动补全功能的实现
2021/01/07 Python
几款主流好用的富文本编辑器(所见即所得常用编辑器)介绍
2021/03/17 Javascript
使用CSS3制作一个简单的进度条(demo)
2017/05/23 HTML / CSS
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
大专生自我鉴定范文
2013/10/01 职场文书
体育专业求职信
2014/07/16 职场文书
环卫个人总结
2015/03/03 职场文书
读《瓦尔登湖》有感:每个人都需要一个瓦尔登湖
2019/10/17 职场文书
springBoot基于webSocket实现扫码登录
2021/06/22 Java/Android
V Rising 服务器搭建图文教程
2022/06/16 Servers