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+APACHE实现用户论证的方法
Oct 09 PHP
PHP编码规范-php coding standard
Mar 16 PHP
PHP 中检查或过滤IP地址的实现代码
Nov 27 PHP
PHP中设置时区方法小结
Jun 03 PHP
基于PHP 面向对象之成员方法详解
May 04 PHP
easyui的tabs update正确用法分享
Mar 21 PHP
初识Laravel
Oct 30 PHP
新浪SAE搭建PHP项目教程
Jan 28 PHP
php批量删除操作(数据访问)
May 23 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
Mar 27 PHP
php文件操作之文件写入字符串、数组的方法分析
Apr 15 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 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
WordPress导航菜单的滚动和淡入淡出效果的实现要点
2015/12/14 PHP
php编程每天必学之验证码
2016/03/03 PHP
PHP中empty,isset,is_null用法和区别
2017/02/19 PHP
详解PHP素材图片上传、下载功能
2019/04/12 PHP
JS 控制CSS样式表
2009/08/20 Javascript
jQuery滚动加载图片效果的实现
2013/03/06 Javascript
javascript运行机制之this详细介绍
2014/02/07 Javascript
express的中间件cookieParser详解
2014/12/04 Javascript
jQuery中ajax的load()方法用法实例
2014/12/26 Javascript
解析jquery easyui tree异步加载子节点问题
2017/03/08 Javascript
微信小程序--onShareAppMessage分享参数用处(页面分享)
2017/04/18 Javascript
jQuery实现下拉菜单的实例代码
2017/06/19 jQuery
微信小程序 sha1 实现密码加密实例详解
2017/07/06 Javascript
JavaScript如何获取到导航条中HTTP信息
2017/10/10 Javascript
vue2.0 循环遍历加载不同图片的方法
2018/03/06 Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
2018/10/28 Javascript
js数组去重的方法总结
2019/01/18 Javascript
在layui tab控件中载入外部html页面的方法
2019/09/04 Javascript
关于vue3.0中的this.$router.replace({ path: '/'})刷新无效果问题
2020/01/16 Javascript
jQuery实现高度灵活的表单验证功能示例【无UI】
2020/04/30 jQuery
基于javascript处理二进制图片流过程详解
2020/06/08 Javascript
[45:32]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
Python查询Mysql时返回字典结构的代码
2012/06/18 Python
python测试mysql写入性能完整实例
2018/01/18 Python
用pandas按列合并两个文件的实例
2018/04/12 Python
Keras Convolution1D与Convolution2D区别说明
2020/05/22 Python
pycharm永久激活超详细教程
2020/10/29 Python
请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
2015/07/16 面试题
军训考核自我鉴定
2014/02/13 职场文书
党的群众路线对照检查材料
2014/08/27 职场文书
庆祝教师节演讲稿
2014/09/03 职场文书
12.4全国法制宣传日活动总结
2014/11/01 职场文书
新店开张宣传语
2015/07/13 职场文书
如何用Node.js编写内存效率高的应用程序
2021/04/30 Javascript
MySQL数据库优化之通过索引解决SQL性能问题
2022/04/10 MySQL
面试官问我Mysql的存储引擎了解多少
2022/08/05 MySQL