PHP快速按行讀取CSV大文件的封裝類(lèi)分享(也適用于其它超大文本文件)
CSV大文件的讀取已經(jīng)在前面講述過(guò)了(PHP按行讀取、處理較大CSV文件的代碼實(shí)例),但是如何快速完整的操作大文件仍然還存在一些問(wèn)題。
1、如何快速獲取CSV大文件的總行數(shù)?
辦法一:直接獲取文件內(nèi)容,使用換行符進(jìn)行拆分得出總行數(shù),這種辦法對(duì)小文件可行,處理大文件時(shí)不可行;
辦法二:使用fgets一行一行遍歷,得出總行數(shù),這種辦法比辦法一好一些,但大文件仍有超時(shí)的可能;
辦法三:借助SplFileObject類(lèi),直接將指針定位到文件末尾,通過(guò)SplFileObject::key方法獲取總行數(shù),這種辦法可行,且高效。
具體實(shí)現(xiàn)方法:
$csv_file = 'path/bigfile.csv';
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek(filesize($csv_file));
echo $spl_object->key();
2、如何快速獲取CSV大文件的數(shù)據(jù)?
仍然使用PHP的SplFileObject類(lèi),通過(guò)seek方法實(shí)現(xiàn)快速定位。
$csv_file = 'path/bigfile.csv';
$start = 100000; // 從第100000行開(kāi)始讀取
$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、綜合上面兩點(diǎn),整理成一個(gè)csv文件讀取的類(lèi):
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;
}
}
調(diào)用方法如下:
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);
其實(shí),上述CsvReader類(lèi)并不只針對(duì)CSV大文件,對(duì)于其他文本類(lèi)型的大文件或超大文件同樣可用,前提是將類(lèi)中fgetcsv方法稍加改動(dòng)為current即可。
相關(guān)文章
php中simplexml_load_string使用實(shí)例分享
這篇文章主要介紹了php中simplexml_load_string使用實(shí)例,需要的朋友可以參考下2014-02-02
PHP安裝threads多線程擴(kuò)展基礎(chǔ)教程
php5.3或以上,且為線程安全版本。apache和php使用的編譯器必須一致,通過(guò)phpinfo()查看Thread Safety為enabled則為線程安全版,通過(guò)phpinfo()查看Compiler項(xiàng)可以知道使用的編譯器,本文給大家介紹PHP安裝threads多線程擴(kuò)展基礎(chǔ)教程,需要的朋友參考下2015-11-11
php實(shí)現(xiàn)微信公眾號(hào)創(chuàng)建自定義菜單功能的實(shí)例代碼
這篇文章主要介紹了php實(shí)現(xiàn)微信公眾號(hào)創(chuàng)建自定義菜單功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
Symfony2使用Doctrine進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)方法實(shí)例總結(jié)
這篇文章主要介紹了Symfony2使用Doctrine進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)方法,結(jié)合實(shí)例形式總結(jié)分析了基于Doctrine的基本查詢(xún)、DQL及查詢(xún)生成器的基本實(shí)現(xiàn)方法,需要的朋友可以參考下2016-03-03
thinkPHP框架實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器示例
這篇文章主要介紹了thinkPHP框架實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器,結(jié)合實(shí)例形式分析了基于thinkPHP框架的用戶登陸、數(shù)值計(jì)算、數(shù)據(jù)庫(kù)讀寫(xiě)、歷史記錄保存等功能相關(guān)實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2018-12-12
php 如何禁用eval() 函數(shù)實(shí)例詳解
在php中eval是一個(gè)函數(shù)并且不能直接禁用了,但eval函數(shù)又相當(dāng)?shù)奈kU(xiǎn)并經(jīng)常會(huì)出現(xiàn)一些問(wèn)題,今天我們就一起來(lái)看看eval函數(shù)對(duì)數(shù)組的操作及php 如何禁用eval() 函數(shù),需要的朋友可以參考下2016-12-12
laravel高級(jí)的Join語(yǔ)法詳解以及使用Join多個(gè)條件
今天小編就為大家分享一篇laravel高級(jí)的Join語(yǔ)法詳解以及使用Join多個(gè)條件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
php面向?qū)ο笈c面向過(guò)程兩種方法給圖片添加文字水印
使用許多編程語(yǔ)言時(shí),你通常只能使用面向?qū)ο蠡蛎嫦蜻^(guò)程二者之一的編程方式。而在PHP中,你可以自由選擇或混用,下面通過(guò)面向?qū)ο笈c面向過(guò)程兩種方法給圖片添加水印,需要的朋友可以參考下2015-08-08

