PHP 大文件的读取和写入有关问题
PHP 大文件的读取和写入问题
在通常的学习和开发中,因为我们很少会接触到大量数据的读取和写入,所以当突然有了这种需求的时候,我们可
能仍然会按照一些比较快捷的方法,像file_get_contents,fread等方法来读取文件,不过这样以来如果读取的文件太
大,就会产生问题,在实现大文件读取和写入的时候查找了网上的一些资料,不过有些例子给的不是很符合我的需
求,所以我就结合网上已有的例子,再写一篇总结性的博客吧。
那么究竟会产生什么问题呢,这就要说一些PHP的底层实现数,file_get_contents和fread来说一下,首先说一下
PHP中文件读取的函数,file_get_contents和fread,这两个函数其实原理是相同的,都是读取内容到系统的内存中,
不过如果只是想将一个文件的内容读入到一个字符串中,请使用file_get_contents(),它的性能比 fread() 好得多。
在读取不是很大的文件还是没有问题的,不过当读取大文件的时候(例如2GB的日志),如果你机器的内存只有4G,
如果你将整个文件全部读取然后存入字符串中,就可能会导致系统的内存爆掉造成卡死,因为还有一部分内存要用于
维持系统的运行和其他进程的运行,既然会这样,我们就需要一些其他办法来避免一次性读取太多的内容,通过这种
办法来实现大文件的读取。
PHP文件读取:
下面这个是网上读取大文件的一个例子,来说明上面内存会爆掉的现象。。
_________________________________无敌分割线_______________________________________
需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容。
实现方法:
1. 直接采用file函数来操作
注:由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的memory_limit = 16M来进行设置,这个值如果设置-1,则内存使用量不受限制.
下面是一段用file来取出这具文件最后一行的代码.
整个代码执行完成耗时 116.9613 (s).
我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了.
上面的例子虽然是读取最后几行的例子,不过由于对文件的内容进行了遍历,所以跟读取整个文件是一样的,不过如
果是为了读取最后几行的内容,也可以直接用fseek来进行定位读取部分内容。
下面我们来一起探讨下如何对大文件进行读取和写入。
大文件读取:
因为要求读取部分,如果文件不是特别大,可以通过file_get_contents或fread自带的分割参数来进行分块来进行读取(这个地方感觉需要加一个sleep函数,来减少IO的峰值大小,不过不知是否正确,希望大牛指点),还有一种方法,就是通过while循环,用fgets来进行逐行的读取,因为fgetss是通过文件指针读取一行,效率是比较高的。
下面附上通过fgets实现的大文件读取并对文件内容进行编码转换(UTF-8 -> GBK)的例子,代码如下:
$file = fopen($old_file_path,"r"); $result = fopen($temporary_file_path,"a"); $re_sign = 0; while(!feof($file)) { $content = fgets($file); $encode = mb_detect_encoding($content, array('ASCII','UTF-8','GB2312','GBK','BIG5')); if ($encode == 'UTF-8') { $str = iconv($encode,"GBK//IGNORE", $content); $encode = mb_detect_encoding($content, array('ASCII','UTF-8','GB2312','GBK','BIG5')); fwrite($result, $str); $re_sign = 1; } else { fwrite($result, $content); } } fclose($file); fclose($result); if($re_sign == 1){ rename($old_file_path, $old_file_path . '.bak' ); rename($temporary_file_path, $old_file_path); } else { unlink($temporary_file_path); }
大文件写入:
大文件的写入相对大文件读取来说产生的代价不是很大,因为文件写入是写入到硬盘中,如果一次性写入文件过多,
只会产生卡硬盘的现象,如果从效率上来讲一次性直接写入的耗时和效率最高,所以大文件的写入的话建议一次性读取后直接写入文件中。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

想了解更多关于开源的内容,请访问:51CTO鸿蒙开发者社区https://ost.51cto.com运行环境DAYU200:4.0.10.16SDK:4.0.10.15IDE:4.0.600一、创建应用点击File->newFile->CreateProgect。选择模版:【OpenHarmony】EmptyAbility:填写项目名,shici,应用包名com.nut.shici,应用存储位置XXX(不要有中文,特殊字符,空格)。CompileSDK10,Model:Stage。Device

使用Java的File.length()函数获取文件的大小文件大小是在处理文件操作时很常见的一个需求,Java提供了一个很方便的方法来获取文件的大小,即使用File类的length()方法。本文将介绍如何使用该方法来获取文件的大小,并给出相应的代码示例。首先,我们需要创建一个File对象来表示我们想要获取大小的文件。以下是创建File对象的方法:Filef

php blob转file的方法:1、创建一个php示例文件;2、通过“function blobToFile(blob) {return new File([blob], 'screenshot.png', { type: 'image/jpeg' })}”方法实现Blob转File即可。

Linux系统如何设置PATH环境变量在Linux系统中,PATH环境变量用于指定系统在命令行中搜索可执行文件的路径。正确设置PATH环境变量可以方便我们在任何位置执行系统命令和自定义命令。本文将介绍如何在Linux系统中设置PATH环境变量,并提供详细的代码示例。查看当前的PATH环境变量在终端中执行以下命令,可以查看当前的PATH环境变量:echo$P

使用Java的File.renameTo()函数重命名文件在Java编程中,我们经常需要对文件进行重命名的操作。Java提供了File类来处理文件操作,其中的renameTo()函数可以方便地重命名文件。本文将介绍如何使用Java的File.renameTo()函数来重命名文件,并提供相应的代码示例。File.renameTo()函数是File类的一个方法,

使用java的File.getParentFile()函数获取文件的父目录在Java编程中,我们经常需要操作文件和文件夹。当我们需要获取文件的父目录时,可以使用Java提供的File.getParentFile()函数来完成。本文将介绍如何使用这个函数并提供代码示例。Java中的File类是用于操作文件和文件夹的主要类。它提供了许多方法来获取和操作文件的属性

使用java的File.getParent()函数获取文件的父路径在Java编程中,我们经常需要操作文件和文件夹。有时候,我们需要获取一个文件的父路径,也就是该文件所在文件夹的路径。Java的File类提供了getParent()方法用于获取文件或文件夹的父路径。File类是Java对文件和文件夹的抽象表示,它提供了一系列操作文件和文件夹的方法。其中,get

设置path环境变量的方法:1、Windows系统,打开“系统属性”,点击“属性”选项,点击“高级系统设置”,在“系统属性”窗口中,选择“高级”标签,然后点击“环境变量”按钮,找到并点击“Path”编辑保存后即可;2、Linux系统,打开终端,打开你的bash配置文件,在文件末尾添加“export PATH=$PATH:文件路径”保存即可;3、MacOS系统,操作同上。
