当你需要处理一个5G的文件里面的数据时,你会怎么做,将文件里面的内容全部读取到一个数组里面去? 显然这种做法对小文件是没有问题的,但是对于大文件还是不行的

这时就需要用到  yield 了 ,注意这是php5.5之后才有的

1.首先我们看一个基本的代码

<?php
function aa($number){
for($i=0;$i<$number;$i++){
$data[] = $i.'-'.time();
}
return $data;
} $result = aa(5);
foreach($result as $value){
sleep(1);//这里停顿1秒
echo $value.'<br />';
}

这是一个正常的代码,我们将传入的数据当做一个很大的数据(虽然目前是5),结果为

0-1555485328
1-1555485328
2-1555485328
3-1555485328
4-1555485328

(1)很明显,我们执行的循序是,先将for里面的全部执行完(因为时间戳都是一样的),然后再执行foreach这个函数。5条是没有问题的,但是如果是五百万条呢,会不会太大,占用太多资源

2.我们再看优化之后的

<?php
function aa($number){
for($i=0;$i<$number;$i++){
yield $i.'-'.time();
}
} $result = aa(5);
foreach($result as $value){
sleep(1);//这里停顿1秒
echo $value.'<br />';
}

利用yield 返回数据,我们再看一下结果

0-1555485647
1-1555485648
2-1555485649
3-1555485650
4-1555485651

(2)我们可以发现,程序会先从for里面拿出一个值,然后利用这个值来进行foreach,当这次循环完了后,再自动去for里面取第二个值。可以发现,只是时间变了,结果内容完全是一样的

像这样一个值一个值的处理,不管你数据有多大,我始终只处理一个值。就很大程度上优化了代码 ,节约了资源

我们来运行一个实例,读取一个txt文件

<?php
function read($path){
$file = fopen($path, "r");
//输出文本中所有的行,直到文件结束为止。
while(! feof($file))
{
yield fgets($file)."<br>";//fgets()函数从文件指针中读取一行
}
fclose($file);
} $a = read('test.txt');
foreach ($a as $val){
echo $val;
}

输出:

第1行
第2行
第3行
第4行
第5行
第6行
第7行
第8行
第9行
第10行
第11行

输出的结果和没用yiled是一样的,看不出来,我们加一个时间戳,并停顿一秒试一下

a, 不用yield

<?php
function read($path){
$file = fopen($path, "r");
//输出文本中所有的行,直到文件结束为止。
while(! feof($file))
{
$data[] = fgets($file).time()."<br>";//fgets()函数从文件指针中读取一行
}
return $data;
fclose($file);
} $a = read('test.txt');
foreach ($a as $val){
sleep(1);
echo $val;
}

结果:

第1行 1555488162
第2行 1555488162
第3行 1555488162
第4行 1555488162
第5行 1555488162
第6行 1555488162
第7行 1555488162
第8行 1555488162
第9行 1555488162
第10行 1555488162
第11行1555488162

b.用yield

<?php
function read($path){
$file = fopen($path, "r");
//输出文本中所有的行,直到文件结束为止。
while(! feof($file))
{
yield fgets($file).time()."<br>";//fgets()函数从文件指针中读取一行
}
fclose($file);
} $a = read('test.txt');
foreach ($a as $val){
sleep(1);
echo $val;
}

结果:

第1行 1555487737
第2行 1555487738
第3行 1555487739
第4行 1555487740
第5行 1555487741
第6行 1555487742
第7行 1555487743
第8行 1555487744
第9行 1555487745
第10行 1555487746
第11行1555487747

(3)发现虽然结果一样,但是他们的执行过程是不一样的。

php 大文件读取的更多相关文章

  1. linux大文件读取

    在生产环境中有时候可能会遇到大文件的读取问题,但是大文件读取如果按照一般的手法.如cat这种都是对io的一个挑战,如果io扛得住还好,如果扛不住 造成的后果,如服务器内存奔溃,日志损坏 方法一: se ...

  2. python大文件读取

    python大文件读取 https://stackoverflow.com/questions/8009882/how-to-read-a-large-file-line-by-line-in-pyt ...

  3. TCP协议传输大文件读取时候的问题

    TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...

  4. Java解决大文件读取的内存问题以及文件流的比较

    Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...

  5. PHP大文件读取操作

    简单的文件读取,一般我们会使用 file_get_contents() 这类方式来直接获取文件的内容.不过这种函数有个严重的问题是它会把文件一次性地加载到内存中,也就是说,它会受到内存的限制.因此,加 ...

  6. 大文件读取方法(C#)

    之前都是用StreamReader.ReadLine方法逐行读取文件,自从.NET4有了File.ReadLines这一利器,就再也不用为大文件发愁了. File.ReadLines在整个文件读取到内 ...

  7. C基础 大文件读取通过标准库

    引言 - 问题的构建 C大部分读取文件的时候采用fgetc, 最近在使用过程中发现性能不是很理想.都懂得fgetc每次只能读取一个字符, IO操作太频繁. 所以性能低. 本文希望通过标准库函数frea ...

  8. dart 大文件读取

    dart 中不可避免会出现文件读取的情况, 甚至是很大的文件, 比如 200M 的文件 如果一次性读入内存,虽然也行得通, 但是如果在 flutter 中开启个 200M 大小的字节数组, 一不小心可 ...

  9. C#大文件读取和查询--内存映射

    笔者最近需要快速查询日志文件,文件大小在4G以上. 需求如下: 1.读取4G左右大小的文件中的指定行,程序运行占用内存不超过500M. 2.希望查询1G以内容,能控制在20s左右. 刚开始觉得这个应该 ...

随机推荐

  1. leetcode693

    class Solution { public: bool hasAlternatingBits(int n) { ; while (n) { ; ) { last = x; } else { if ...

  2. Java微信公众平台开发(十五)--微信JSSDK的使用

    转自:http://www.cuiyongzhi.com/post/63.html 在前面的文章中有介绍到我们在微信web开发过程中常常用到的 [微信JSSDK中Config配置] ,但是我们在真正的 ...

  3. FFmpeg新版本(2016年10月份以后) 支持硬件解码

    FFmpeg provides a subsystem for hardware acceleration. Hardware acceleration allows to use specific ...

  4. 你是真的了解ssh吗 说说你不知道的ssh

    Ssh命令——基石天赋 主要参数说明: -l 指定登入用户 -p 设置端口号 -f 后台运行,并推荐加上 -n 参数 -n 将标准输入重定向到 /dev/null,防止读取标准输入 -N 不执行远程命 ...

  5. Vulkan Tutorial 09 图像与视图

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 使用任何的VkImage,包括在交换链或者渲染管线中的,我们都需要创建VkImage ...

  6. Oracle 环境下 GoldenGate 集成抽取(Integrated Capture)模式与传统抽取模式(Classic Capture)间的切换

    检查抽取进程模式 在 GGSCI 环境下,执行类似如下语句查看特定进程的状态. GGSCI> info <Group_Name> 其中,<Group_Name> 为进程名 ...

  7. 【原创】4. MYSQL++ 之 SQLTypeAdapter类型、SQLQueryParms类型 与 SQLBuffer

    1. mysqlpp::SQLBuffer 该类型其实就是SQLTypeAdapter传入的各种类型(int, string, double, long, String, …) 的包装,包装的结果就是 ...

  8. Hibernate和Mybatis区别 详细 有用

    1.开发上手难度 hibernate的真正掌握(封装的功能和特性非常多)要比Mybatis来得难. 在真正产品级应用上要用Hibernate,不仅对开发人员的要求高,hibernate往往还不适合(多 ...

  9. Solidity开发、测试、部署

    这篇文章很详细的列举了几种方式来开始solidity开发: https://medium.com/@davekaj/solidity-tips-and-tricks-for-beginners-bui ...

  10. 默默的发现在网上找到的hook NtQueryDirectoryFile......

    默默的发现在网上找到的hook  NtQueryDirectoryFile...... hook  NtQueryDirectoryFile是为了实现文件隐藏,然后就发现在网上发现的代码版本似乎同一个 ...