文档章节

PHP快速读取CSV大文件

 蜗牛奔跑
发布于 2015/06/17 14:38
字数 845
阅读 19
收藏 0
点赞 0
评论 0

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);

 

综合上面两点,整理成一个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读取CSV大文件导入数据库



PHP如何对CSV大文件进行读取并导入数据库?

对于数百万条数据量的CSV文件,文件大小可能达到数百M,如果简单读取的话很可能出现超时或者卡死的现象。

为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。

下面这个函数是读取CSV文件中指定的某几行数据:

/** * csv_get_lines 读取CSV文件中的某几行数据 * @param $csvfile csv文件路径 * @param $lines 读取行数 * @param $offset 起始行数 * @return array * */function csv_get_lines($csvfile, $lines, $offset = 0) {
    if(!$fp = fopen($csvfile, 'r')) {
    	return false;
    }
    $i = $j = 0;
	while (false !== ($line = fgets($fp))) {
		if($i++ < $offset) {
			continue; 
		}
		break;
	}
	$data = array();
	while(($j++ < $lines) && !feof($fp)) {
		$data[] = fgetcsv($fp);
	}
	fclose($fp);
    return $data;}

调用方法:

 

$data = csv_get_lines('path/bigfile.csv', 10, 2000000);

print_r($data);

函数主要采用行定位的思路,通过跳过起始行数来实现文件指针定位。

至于数据如何入库本文不再详细讲述。

上述函数对500M以内的文件进行过测试,运行通畅,对于更大的文件未做测试,请斟酌使用或加以改进。


本文转载自:

共有 人打赏支持
粉丝 36
博文 596
码字总数 114025
作品 0
海淀
PHP读取CSV大文件导入数据库

PHP如何对CSV大文件进行读取并导入数据库? 对于数百万条数据量的CSV文件,文件大小可能达到数百M,如果简单读取的话很可能出现超时或者卡死的现象。 为了成功将CSV文件里的数据导入数据库,...

学习环境
2015/09/21
493
0
php csv文件的读取,写入,输出下载操作详解

php对csv文件的读取,写入,输出下载操作。 代码: <?php //print_r($data); //此为一个数组,要获得每一个数据,访问数组下标即可$goods_list[] = $data; //printr($goodslist);echo $goods_l...

mysoftsky
2013/08/10
0
0
PHP读取csv文件内容的方法详解

PHP读取csv文件的内容的方法。 一次性读取csv文件内所有行的数据 <?php$file = fopen('windows2011s.csv','r');while ($data = fgetcsv($file)) { //每次读取CSV里面的一行内容//print_r($da...

mysoftsky
2013/08/10
0
3
PHP读取创建txt,doc,xls,pdf类型文件

PHP读取或者创建txt,doc,xls,pdf各个类型文件的方法. php读取(文本.txt)文件: 一般是使用fopen、fgets的方法,例如: <?php $fp=fopen('文件名.txt','r'); for ($i=1;$i<100;$i++) fgets(...

durban
2012/03/31
0
3
form表单通过ajax提交文件

例子:在页面上传一个csv文件,web服务器端用php解析上传的csv文件并入库 前端页面代码: form的enctype必须是multipart/form-data才可以上传多个文件,ajax通过FormData来上传数据,ajax的c...

ShutLove
01/04
0
0
PHP 利用CSV的首行为二维数组命名

PHP有一个方法可以直接读取CSV文件内容的,就是fgetcsv(),具体参数及说明可以查看一下PHP手册。 今晚也许是闲得蛋疼,或者怎样,通过这个函数写了一个读取CSV文件内容的函数,可以对应表格中...

Tingel
2012/05/08
0
0
网站推广php读excel文件的方法

网站推广常用的用PHP读取EXCEL的方法有以下三种,各自有各自的优缺点。个人推荐用第三种方法,因为它可以跨平台使用。 1. 以.csv格式读取 将.xls转换成.csv的文本格式,然后再用PHP分析这个文...

网络营销
2012/02/20
0
0
Pandas读取MongoDB数据的另一种方式

之前介绍了在Pandas中读取MongoDB数据的方法,在索引出数据之后,将结果转换为列表list,然后在传入一个pandas的DataFrame中。 这种方法很简单,但是有一个问题,就是在数据量大的时候,会大...

州的先生
2017/11/20
0
0
Python读取MongoDB数据的另一种方式

文章首发:http://zmister.com/archives/161.html 不玩虚的Python爬虫、数据分析、机器学习、GUI开发、渗透测试,http://zmister.com/ 之前介绍了在Pandas中读取MongoDB数据的方法,在索引出...

州的先生
2017/11/21
0
0
PHP tools:CSV文件处理

生成的CSV文件 一、生成CSV文件 1、主要函数: fputcsv—将行格式化为 CSV 并写入文件指针 int fputcsv ( resource $handle , array $fields [, string $delimiter = ',' [, string $enclosu...

Nosee123
03/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
12分钟前
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0
iptables规则备份和恢复、firewalld的9个zone以及操作和service的操作

保存以及备份iptalbes规则 设定了的防火墙规则要进行保存,否则系统重启后这些规则就没有了,使用命令 ”service iptables save ” 会把设定好的防火墙规则保存到文件/etc/sysconfig/iptabl...

黄昏残影
昨天
0
0
k8s image

k8s.gcr.io/kube-apiserver-amd64:v1.11.0k8s.gcr.io/kube-controller-manager-amd64:v1.11.0k8s.gcr.io/kube-scheduler-amd64:v1.11.0k8s.gcr.io/kube-proxy-amd64:v1.11.0k8s.gcr.......

分秒
昨天
0
0
数据结构--排序

这篇博客包含了数据结构中多种的排序算法: (1)简单选择:第一趟在A[0]~A[n-1]之间找到最小的,与A[0]进行交换,之后在A[1]~A[n-1]之间进行。。。第i趟在A[i-1]~A[n-1]之间找到最小的,最后...

wangxuwei
昨天
1
0
一名3年工作经验的java程序员应该具备的职业技能

一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西—-但是如果你掌握得越多,最终能得到的评价、拿到的薪...

老道士
昨天
2
0
MAC安装JDK

一 :在JDK官网下载对应的JDK版本 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 二:找到JDK安装目录,点击会出现图标,双击图标自动安装,勾选默...

WALK_MAN
昨天
0
0
关于MySQL卸载重新安装的问题 windows

大体上一共分为3步,那么我们就美其名曰——三步走搞定MySQL安装 为什么说3步呢,如果你非要计较说我一次就重新安装成功了,就当我没说,这些是说给那些经常安装失败的同学看的! 切记,如若...

yeahlife
昨天
0
0
Linux 技巧:让进程在后台可靠运行的几种方法

我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。如何让命令提交后不受本地关闭终端窗口/网络断...

mskk
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部