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 相关文章推荐
用PHP4访问Oracle815
Oct 09 PHP
利用php来自动调用不同服务器上的flash
Oct 09 PHP
yii操作cookie实例简介
Jul 09 PHP
php数组合并与拆分实例分析
Jun 12 PHP
Linux+Nginx+MySQL下配置论坛程序Discuz的基本教程
Dec 23 PHP
如何打开php的gd2库
Feb 09 PHP
php实现购物车产品删除功能(2)
Jul 23 PHP
PHP对象相关知识总结
Apr 09 PHP
php实现二叉树中和为某一值的路径方法
Oct 14 PHP
laravel-admin 实现给grid的列添加行数序号的方法
Oct 08 PHP
php封装的page分页类完整实例代码
Feb 01 PHP
PHP基本语法
Mar 31 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读取msn上的用户信息类
2008/12/05 PHP
浅析ThinkPHP的模板输出功能
2014/07/01 PHP
PHP实现接收二进制流转换成图片的方法
2017/01/10 PHP
Thinkphp 空操作、空控制器、命名空间(详解)
2017/05/05 PHP
PHP实现递归的三种方法
2020/07/04 PHP
node.js中的fs.close方法使用说明
2014/12/17 Javascript
JS 实现倒计时数字时钟效果【附实例代码】
2016/03/30 Javascript
浅谈JS中的!=、== 、!==、===的用法和区别
2016/09/24 Javascript
解决拦截器对ajax请求的拦截实例详解
2016/12/21 Javascript
jQuery实现Table表格隔行变色及高亮显示当前选择行效果示例
2017/02/14 Javascript
Vue中的v-cloak使用解读
2017/03/27 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
vue.js模仿京东省市区三级联动的选择组件实例代码
2017/11/22 Javascript
浅谈Vuex@2.3.0 中的 state 支持函数申明
2017/11/22 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
2018/08/31 Javascript
微信小程序mpvue点击按钮获取button值的方法
2019/05/29 Javascript
如何在vue中使用HTML 5 拖放API
2021/01/14 Vue.js
深入讲解Java编程中类的生命周期
2016/02/05 Python
详谈Pandas中iloc和loc以及ix的区别
2018/06/08 Python
Python enumerate函数功能与用法示例
2019/03/01 Python
python basemap 画出经纬度并标定的实例
2019/07/09 Python
Python3 assert断言实现原理解析
2020/03/02 Python
基于python实现检索标记敏感词并输出
2020/05/07 Python
使用keras实现孪生网络中的权值共享教程
2020/06/11 Python
C++和python实现阿姆斯特朗数字查找实例代码
2020/12/07 Python
为什么要使用servlet
2016/01/17 面试题
学期自我鉴定
2013/11/04 职场文书
《搭石》教学反思
2014/04/07 职场文书
餐饮商业计划书范文
2014/04/29 职场文书
中文专业自荐书
2014/06/29 职场文书
简易离婚协议书范本2014
2014/10/15 职场文书
社区义诊通知
2015/04/24 职场文书
因公司原因离职的辞职信范文
2015/05/12 职场文书
JavaScript中的宏任务和微任务详情
2021/11/27 Javascript
MySQL中的全表扫描和索引树扫描
2022/05/15 MySQL
PHP 时间处理类Carbon
2022/05/20 PHP