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 相关文章推荐
smtp邮件发送一例
Oct 09 PHP
PHP新手上路(十二)
Oct 09 PHP
php实现单链表的实例代码
Mar 22 PHP
PHP中防止SQL注入方法详解
Dec 25 PHP
php实现读取手机客户端浏览器的类
Jan 09 PHP
Laravel 5框架学习之模型、控制器、视图基础流程
Apr 08 PHP
服务器迁移php版本不同可能诱发的问题
Dec 22 PHP
Yii隐藏URL中index.php的方法
Jul 12 PHP
PHP连接MYSQL数据库的3种常用方法
Feb 27 PHP
PHP实现文件上传功能实例代码
May 18 PHP
PHP 获取 ping 时间的实现方法
Sep 29 PHP
详解php语言最牛掰的Laravel框架
Nov 20 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
德生PL990的分析评价
2021/03/02 无线电
PHP中用header图片地址 简单隐藏图片源地址
2008/04/09 PHP
php 日期时间处理函数小结
2009/12/18 PHP
jquery 可拖拽的窗体控件实现代码
2010/03/21 Javascript
js获取height和width的方法说明
2013/01/06 Javascript
js简单实现让文本框内容逐个字的显示出来
2013/10/22 Javascript
详细分析JavaScript变量类型
2015/07/08 Javascript
jquery实现叠层3D文字特效代码分享
2015/08/21 Javascript
基于JavaScript实现通用tab选项卡(通用性强)
2016/01/07 Javascript
jQuery基于ID调用指定iframe页面内的方法
2016/07/06 Javascript
jQuery实现自动调用和触发某个事件的方法
2016/11/18 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
2017/03/03 Javascript
微信小程序中遇到的iOS兼容性问题小结
2018/11/14 Javascript
详解Vue 匿名、具名和作用域插槽的使用方法
2019/04/22 Javascript
jQuery实现高级检索功能
2019/05/28 jQuery
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
Angular.JS读取数据库数据调用完整实例
2019/07/02 Javascript
解决layui 表单元素radio不显示渲染的问题
2019/09/04 Javascript
webpack4 optimization使用总结
2019/11/10 Javascript
JavaScript实现横版菜单栏
2020/03/17 Javascript
Webpack中SplitChunksPlugin 配置参数详解
2020/03/24 Javascript
JS实现图片懒加载(lazyload)过程详解
2020/04/02 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
[02:40]DOTA2英雄基础教程 巨牙海民
2013/12/23 DOTA
[00:32]2018DOTA2亚洲邀请赛VG出场
2018/04/03 DOTA
用Python展示动态规则法用以解决重叠子问题的示例
2015/04/02 Python
Tensorflow设置显存自适应,显存比例的操作
2020/02/03 Python
Django-simple-captcha验证码包使用方法详解
2020/11/28 Python
毕业生找工作的求职信范文
2013/12/24 职场文书
入学申请自荐信范文
2014/02/26 职场文书
继承权公证书
2014/04/09 职场文书
财务部绩效考核方案
2014/05/04 职场文书
小学清明节活动总结
2014/07/04 职场文书
只需要100行Python代码就可以实现的贪吃蛇小游戏
2021/05/27 Python
深入解析MySQL索引数据结构
2021/10/16 MySQL
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL