热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP中Swoole多进程读取大文件示例

这篇文章主要讲解了“PHP中Swoole多进程读取大文件示例”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究

这篇文章主要讲解了“PHP中Swoole多进程读取大文件示例”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP中Swoole多进程读取大文件示例”吧!

PHP读取大文件源码示例,通过PHP读取过大、超大型文件的思路及解决方案。

在日常读取文件时,若文件 不是很大,通常使用file_get_contents,将内容一次性载入的变量中,也可以远程加载网页或者远端文件。

若加载超过PHP限制的内存大小,或者超过本机内存大小的文件进程就会报错或者崩掉。

为了解决这个问题,我们采用使用完毕并释放的原则来读取大文件。

单线程读入

如果不考虑多线程的情况下,单线程读取大文件采用while fread就可以实现。

如下代码

$handle = fopen("./big.txt", "rb");
while (!feof($handle)) {
  $contents = fread($handle, 8192);
  // 业务处理
  unset($contents); // 释放掉变量
}
fclose($handle);

feof是判断是否到文件尾,如果没有到文件尾,则会一直while循环,并执行读取操作。每次读取8192字节,然后使用过后将其释放掉。

往往很多文件并不是一行的,有多行内容。需要将每行内容读取出来当做一条数据处理,也可以使用fgets。

即如下代码:

$handle = fopen("./big.txt", "rb");
while (!feof($handle)) {
  $contents = fgets($handle, 1024);
  // 业务处理
  unset($contents); // 释放掉变量
}
fclose($handle);

这里的fgets第二个参数,默认为1024字节。即默认读取一行数据,如果一行数据小于1024字节,则完整读取。如果超出1024字节,则只取前1024字节。遇到换行符"\n"或者"\r\n"或者结束符会停止读取。

如果遇到变态的文件,很多行都只有1000长度,某一行有8000长度,如果在不清楚的情况下,就很难掌控,若要完整读取就需要指定读取的最大字节,8000才能将每一行完整读取。

还有一种方法就是自己处理换行符。默认读取1024字节,然后放置到内存中,使用过后再将其释放。这种操作很节省内存,但是在逻辑处理上需要自己处理换行符。

如,读取1024字节,没有换行符,则保存数据继续读取。再读取1024字节,判断其中是否有换行符,如果有则处理最开始到换行符中的数据。再将剩下的数据保存,等待下一次读取,直到整个文件读取完毕。

$handle = fopen("./big.txt", "rb");
$contents = "";
while (!feof($handle)) {
  $contents .= fread($handle, 8192);

  // 判断读取到的内容是否包含换行符,包含则进入循环体
  while(strpos($contents, "\n") !== false){
      $eol_pos= strpos($contents, "\n");
      $line = substr($contents, 0, $eol_pos);
      // $line为一行的数据,进行业务处理,并释放
      unset($line);

      $contents = substr($eol_pos, 0);// 将剩余内容放置到变量中以供下次使用
  }
}
fclose($handle);

多线程读取

PHP默认没有多线程,这里可以采用多进程的方式实现,或者swoole的多进程来实现。

例如读取一个8GB文件,分8个线程,每个线程读取1GB数据内容。或者更多线程进行拆分工作内容。

获取文件大小

首先第一步,就是获取整个文件的体积大小,然后计算每个线程应该负责处理的一部分内容。

function length($filename)
{
	$handle = fopen($filename, "rb");
	$currentPos = ftell($handle);
	fseek($handle, 0, SEEK_END);
	$length = ftell($handle);
	fseek($handle, $currentPos);
	// $length 文件总长度
	return $length;
}
echo length("./big.txt");

处理逻辑实现过程

这里主要说明下作了哪些内容,首先是设定分配总的线程数。然后根据设置的线程数,计算每个线程要读取的数据大小,即从哪里开始读,读到哪里结束。

然后必定会出现拆分后,读到不完整行的情况,在这里来解决这种前半行或者后半行的意外情况。

解决逻辑就是,假设线程开始的读取位置在某一行的中间,我们一个字符向前移动,移动到上个换行符(也可能是最开始)即可获取到整行文本内容。

处理掉残行数据之后,使用yield来传递数据给业务处理。

$filename = "./big.txt";
$maxProcess = 8;// 分配8个线程


$length = length($filename);
$singleProcessLength = ceil($length / $maxProcess);

// 线程负责读取的内容
function processRead($filename, $index, $singleProcessLength)
{
	$fh = fopen($filename, 'r');
	
	$beginPos = $index * $singleProcessLength;
	//结束位置=线程序列*线程处理数据长度+线程处理数据 - 1 (长度转指针,实际结束指针小于结束长度)
	$endPos = $index * $singleProcessLength + $singleProcessLength - 1;

	fseek($fh, $beginPos);
	echo '线程:' . $index . ',起始位置:' . $beginPos . ',结束位置:' . $endPos . PHP_EOL;
	//移动到上个\n 以便首次顺利获取整行内容
	while (fseek($fh, -1, SEEK_CUR) === 0) {
		if (fread($fh, 1) == "\n" || ftell($fh) <= 0) {
			break;
		}
		fseek($fh, -1, SEEK_CUR);
	}
	echo &#39;线程:&#39; . $index . &#39;,移动完毕!!!!!&#39; . PHP_EOL;

	//整行读取数据
	//结束时位置超过预计结束位置是正常状况,fgets 读取一整行内容
	//预计结束位置可能在行内,所以产生不同结果。
	while (ftell($fh) <= $endPos && !feof($fh)) {
		yield $raw = fgets($fh);
	}
	echo &#39;进程&#39; . $index . &#39;结束时 指针位置:&#39; . ftell($fh) . &#39;, 应该到:&#39; . $endPos . PHP_EOL;
	fclose($fh);
}

foreach(range(0,$maxProcess - 1) as $index){
	// 多线程采用多线程的方式创建,这里采用yield回调。
	foreach(processRead($filename, $index, $singleProcessLength) as $value){
        // $value为每一行的内容,处理后释放
        unset($value);
    } 
}

感谢各位的阅读,以上就是“PHP中Swoole多进程读取大文件示例”的内容了,经过本文的学习后,相信大家对PHP中Swoole多进程读取大文件示例这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程笔记,小编将为大家推送更多相关知识点的文章,欢迎关注!


推荐阅读
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • Python多线程编程技巧与实战应用详解 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • 本文详细介绍了如何使用Python的多进程技术来高效地分块读取超大文件,并将其输出为多个文件。通过这种方式,可以显著提高读取速度和处理效率。 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • 本文介绍如何使用OpenCV和线性支持向量机(SVM)模型来开发一个简单的人脸识别系统,特别关注在只有一个用户数据集时的处理方法。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文介绍了如何利用 `matplotlib` 库中的 `FuncAnimation` 类将 Python 中的动态图像保存为视频文件。通过详细解释 `FuncAnimation` 类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • Python 序列图分割与可视化编程入门教程
    本文介绍了如何使用 Python 进行序列图的快速分割与可视化。通过一个实际案例,详细展示了从需求分析到代码实现的全过程。具体包括如何读取序列图数据、应用分割算法以及利用可视化库生成直观的图表,帮助非编程背景的用户也能轻松上手。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文将继续探讨 JavaScript 函数式编程的高级技巧及其实际应用。通过一个具体的寻路算法示例,我们将深入分析如何利用函数式编程的思想解决复杂问题。示例中,节点之间的连线代表路径,连线上的数字表示两点间的距离。我们将详细讲解如何通过递归和高阶函数等技术实现高效的寻路算法。 ... [详细]
author-avatar
or70woo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有