生成器来解决大文件读取,大数据下载

Posted FollowYou_博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成器来解决大文件读取,大数据下载相关的知识,希望对你有一定的参考价值。

场景

电商平台想要导出一年的报表数据,数据可能有百万,平常的做法是查出所有数据放到数组或对象中,再进行excel导出,一般情况下,数据不是很多这种是没什么问题,但百万级别的数据一下读到内存中,服务器会一下崩溃,内存溢出。通常情况下也不会做这种需求,产品提出来你可以骂两句怼回去,但老板说我就需要这个功能,你苦口婆心说几句,但是还是要做啊。生成器可以帮我做到这些,理解概念可以看看这里

下载文件

  //实现下载大文件,解决内存溢出
    public function actionExport(){

        $filename =  \'sun.csv\'; //设置文件名
        header(\'Content-Type: text/csv\');
        header("Content-Disposition: attachment;filename={$filename}");

        $fp = fopen(\'php://output\', \'w\');

        $sql = \'select * from "SCM_tbiostockDtl"\';

        //非迭代器实现  十万多条数据,导出csv服务器直接崩溃,内存溢出
//        $list = Yii::$app->db->createCommand($sql)->queryAll();

        //PDO::query() 本身由迭代器实现
        $pdo = new \\PDO(\'pgsql:host=192.168.33.30;port=5432;dbname=jump\', \'postgres\', \'123456\');
        $pdo->setAttribute(\\PDO::mysql_ATTR_USE_BUFFERED_QUERY, false);
        $list = $pdo->query($sql);

        foreach ( $list  as  $fields ) {
            fputcsv ( $fp ,  $fields );
        }

        fclose ( $fp );
    }

读取大文件

  //读取大文件
    public function actionRead(){

        $result = $this->readCsv(Yii::$app->basePath.\'/web/file/sun.csv\');

        foreach ($result as $v){
            echo "<pre>";
            var_dump( $v);
            echo "</pre>";
        }

    }

    #生成器
    function readCsv( $file ){

        $fp = fopen($file,\'rb\');

        while( !feof($fp) ){
            yield fgetcsv($fp);
        }

        fclose($fp);
    }

代码细节可以看我的github片段

以上是关于生成器来解决大文件读取,大数据下载的主要内容,如果未能解决你的问题,请参考以下文章

解决java读取大文件内存溢出问题,如何在不重

从文件中读取大(450000+ 字符)字符串

java读取大文件时内存溢出问题

python 如何读取大文件

基于RMI服务传输大文件的完整解决方案

Python3读取大文件的方法