PHP/Shell大文件数据统计并且排序
诸多大互联网公司的面试都会有这么个问题,有个4G的文件,如何用只有1G内存的机器去计算文件中出现次数做多的数字(假设1行是1个数组,例如QQ号码)。如果这个文件只有4B或者几十兆,那么最简单的办法就是直接读取这个文件后进行分析统计。但是这个是4G的文件,当然也可能是几十G甚至几百G的文件,这就不是直接读取能解决了的。
同样对于如此大的文件,单纯用PHP做是肯定行不通的,我的思路是不管多大文件,首先要切割为多个应用可以承受的小文件,然后批量或者依次分析统计小文件后再把总的结果汇总后统计出符合要求的最终结果。类似于比较流行的MapReduce模型,其核心思想就是“Map(映射)”和“Reduce(化简)”,加上分布式的文件处理,当然我能理解和使用到的只有Reduce后去处理。
假设有1个10亿行的文件,每行一个6位-10位不等的QQ号码,那么我需要解决的就是计算在这10亿个QQ号码中,重复最多的前10个号码,使用下面的PHP脚本生成这个文件,很可能这个随机数中不会出现重复,但是我们假设这里面会有重复的数字出现。
代码如下 | 复制代码 |
$fp = fopen('qq.txt','w+'); |
生成文件的世界比较长,Linux下直接使用php-client运行PHP文件会比较节省时间,当然也可以使用其他方式生成文件。生成的文件大约11G。
然后使用Linux Split切割文件,切割标准为每100万行数据1个文件。
代码如下 | 复制代码 |
split -l 1000000 -a 3 qq.txt qqfile |
qq.txt被分割为名字是qqfileaaa到qqfilebml的1000个文件,每个文件11mb大小,这时再使用任何处理方法都会比较简单了。我还是使用PHP进行分析统计:
代码如下 | 复制代码 |
$results = array(); |
这样每个样本取前10个,最后放到一起分析统计,不排除有个数在每个样本中都排名第11位但是总数绝对在前10的可能性,所以后面统计计算算法还需要改进。
也许有人说使用Linux中的awk和sort命令可以完成排序,但是我试了下如果是小文件还可以实现,但是11G的文件,不管是内存还是时间都无法承受。下面是我改的1个awk+sort的脚本,或许是写法有问题,求牛人指导。
代码如下 | 复制代码 |
awk -F '\@' '{name[$1]++ } END {for (count in name) print name[count],count}' qq.txt |sort -n > 123.txt |
互联网几何级增长,未来不管是大文件处理还是可能存在的大数据都存在很大的需求空间
如果你使用的wamp集成安装环境的话,那么你php的配置是在D:/wamp/bin/apache/Apache2.2.17/bin
你要先把他复制覆盖掉D:/wamp/bin/php/php5.3.3下的php.ini,否则当你调用扩展函数的时候会报错误如:Fatal error: Call to undefined function
如果你懒得写那么大长串php的路径,你也可以把D:/wamp/bin/php/php5.3.3加到环境变量path里面。
另外关于传参的问题。 比如我要执行test.php?a=123
命令行中我们就可以写 php test.php 123
在test.php中使用$argv[1]来接收123.
建一个简单的文本文件,其中包含有以下PHP代码,并把它保存为hello.php:
代码如下 | 复制代码 |
<?php |
现在,试着在命令行提示符下运行这个程序,方法是调用CLI可执行文件并提供脚本的文件名:
代码如下 | 复制代码 |
#php phphello.php 输出Hello from the CLI |
附上一个bat的可执行文件作为参考
代码如下 | 复制代码 |
@echo off php D:/wamp/www/taobao/items.php 158345687 php D:/wamp/www/taobao/refunds_up.php 158345687 php D:/wamp/www/taobao/trade.php 158345687 echo.&echo 请按任意键关闭BAT窗口...&pause exit |
一些常用的执行命令的代码
下是 PHP 二进制文件(即 php.exe 程序)提供的命令行模式的选项参数,您随时可以通过 PHP -h 命令来查询这些参数。
Usage: php [options] [-f] <file> [args...]
php [options] -r <code> [args...]
php [options] [-- args...]
-s Display colour syntax highlighted source.
-w Display source with stripped comments and whitespace.
-f <file> Parse <file>.
-v Version number
-c <path>|<file> Look for php.ini file in this directory
-a Run interactively
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-z <file> Load Zend extension <file>.
-l Syntax check only (lint)
-m Show compiled in modules
-i PHP information
-r <code> Run PHP <code> without using script tags <?..?>
-h This help
args... Arguments passed to script. Use -- args when first argument
starts with - or script is read from stdin
CLI SAPI 模块有以下三种不同的方法来获取您要运行的 PHP 代码:
在windows环境下,尽量使用双引号, 在linux环境下则尽量使用单引号来完成。
1.让 PHP 运行指定文件。
代码如下 | 复制代码 |
php my_script.php |
以上两种方法(使用或不使用 -f 参数)都能够运行给定的 my_script.php 文件。您可以选择任何文件来运行,您指定的 PHP 脚本并非必须要以 .php 为扩展名,它们可以有任意的文件名和扩展名。
2.在命令行直接运行 PHP 代码。
代码如下 | 复制代码 |
php -r "print_r(get_defined_constants());" |
在使用这种方法时,请您注意外壳变量的替代及引号的使用。
注: 请仔细阅读以上范例,在运行代码时没有开始和结束的标记符!加上 -r 参数后,这些标记符是不需要的,加上它们会导致语法错误。
3.通过标准输入(stdin)提供需要运行的 PHP 代码。
以上用法给我们提供了非常强大的功能,使得我们可以如下范例所示,动态地生成 PHP 代码并通过命令行运行这些代码:
代码如下 | 复制代码 |
$ some_application | some_filter | php | sort -u >final_output.txt |
fopen函数实例
ob_start : 打开输出缓冲
readfile : 读入一个文件并写入到输出缓冲
返回从文件中读入的字节数。如果出错返回 FALSE 并且除非是以 @readfile() 形式调用,否则会显示错误信息。
ob_get_contents : Return the contents of the output buffer(返回输出缓冲的内容)
This will return the contents of the output buffer without clearing it or FALSE, if output buffering isn’t active. (如果输出缓冲没有活动(打开),则返回 FALSE)
ob_end_clean() : Clean (erase) the output buffer and turn off output buffering(清除输出缓冲)
代码如下 | 复制代码 |
|
php下载远程图片函数 可伪造来路
$gurl 要下载的图片地址
$rfurl 来路。如果目标图像做了防盗链设置,可以绕过。
$filename 下载图片保存的文件名,相对路径,不要用realpath
$gcookie 调整cookie 伪造的cookie
$JumpCount 跳转计数
$maxtime 最大次数
调用方法:DownImageKeep(“http://www.baidu.com/img/baidu_jgylogo2.gif”,”http://baidu.com”,”a.gif”,”",0,10);
代码如下 | 复制代码 |
function DownImageKeep($gurl, $rfurl, $filename, $gcookie=”", $JumpCount=0, $maxtime=30) //获取应答头 if(preg_match(“/^3/”, $m_httphead["http-state"])) //到达指定大小结束 //获取详细应答头 |
实例1
直接使用txt文件进行统计的代码
代码如下 | 复制代码 |
<?php function counter($f_value) |
上面使用的是txt文件,下面我们来介绍一个mysql数据库操作实例
代码如下 | 复制代码 |
CREATE TABLE `mycounter` ( |
函数
代码如下 | 复制代码 |
<?PHP public function ShowMyCounter(){ //定义变量 $IsGone = FALSE; //读取数据 $querysql = "SELECT * FROM `mycounter` WHERE id = Ƈ' "; $queryset = mysql_query($querysql); $row = mysql_fetch_array($queryset); //获得时间量 $DateNow = date('Y-m-d'); $RecordDate = $row['RecordDate']; $DateNow_explode = explode("-",$DateNow); $RecordDate_explode = explode("-",$RecordDate); //判断是否已过去一天 if( $DateNow_explode[0] > $RecordDate_explode[0]) $IsGone = TRUE; else if( $DateNow_explode[0] == $RecordDate_explode[0] ){ if( $DateNow_explode[1] > $RecordDate_explode[1] ) $IsGone = TRUE; else if( $DateNow_explode[1] == $RecordDate_explode[1] ){ if( $DateNow_explode[2] > $RecordDate_explode[2] ) $IsGone = TRUE; }else BREAK; }else BREAK; //根据IsGone进行相应操作 IF($IsGone) { $RecordDate = $DateNow; $CounterToday = 0; $CounterLastDay = $row['CounterToday']; $upd_sql = "update mycounter set RecordDate = '$RecordDate',CounterToday = '$CounterToday',CounterLastDay = '$CounterLastDay' WHERE id = Ƈ' "; mysql_query($upd_sql); } //再次获取数据 $querysql = "SELECT * FROM `mycounter` WHERE id = Ƈ' "; $queryset = mysql_query($querysql); $Counter = $row['Counter']; $CounterToday = $row['CounterToday']; $CounterLastDay = $row['CounterLastDay']; if($row = mysql_fetch_array($queryset) ){ if( $_COOKIE["user"] != "oldGuest" ){ $Counter = ++$row['Counter']; $CounterToday = ++$row['CounterToday']; $upd_sql = "update mycounter set counter = '$Counter',CounterToday = '$CounterToday' WHERE id = Ƈ' "; $myquery = mysql_query($upd_sql); } echo "总访问量:".$Counter; echo " "; echo "今日流量:".$CounterToday; echo " "; echo "昨日流量:".$CounterLastDay; }else{//如果数据库为空时,相应的操作 } } ?> |
当然,需要在文件第一行开始写出如下代码:
代码如下 | 复制代码 |
<?PHP |
如果是静态页面我们上面的方法是不可以实现的,但下面再举一个不错的统计实例
代码如下 | 复制代码 |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <mce:script language="javascript" src="count.php?aid=1&t=show" mce_src="count.php?aid=1&t=show"></mce:script> <mce:script language="javascript" src="count.php?aid=1" mce_src="count.php?aid=1"></mce:script> </head> <body> <h1>php统计静态html页面浏览访问次数代码</h1> <hr> </body> </html> |
count.php代码
代码如下 | 复制代码 |
<?php |
数据库
代码如下 | 复制代码 |
-- |
问题原因:
如果开启了IPv6,curl默认会优先解析 IPv6,在对应域名没有 IPv6 的情况下,会等待 IPv6 dns解析失败 timeout 之后才按以前的正常流程去找 IPv4。在程序中我对curl获取内容都作了较为严格的超时限制,所以就会造成无法获取内容的问题。
解决的方法是设置默认访问为ipv4,php的curl设置方法具体如下
代码如下 | 复制代码 |
$ch = curl_init(); //设置curl请求连接时的最长秒数,如果设置为0,则无限 |
注:curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4) 只有在php版本5.3及以上版本,curl版本7.10.8及以上版本时,以上设置才生效。
相关文章
- 下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
Jupyter Notebook读取csv文件出现的问题及解决
这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06- 有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
- C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
php无刷新利用iframe实现页面无刷新上传文件(1/2)
利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25- 要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
- 又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
- 这篇文章主要介绍了C#路径,文件,目录及IO常见操作,较为详细的分析并汇总了C#关于路径,文件,目录及IO常见操作,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
- 这篇文章主要为大家详细介绍了js实现列表按字母排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-11
- 这篇文章主要介绍了C#使用StreamWriter写入文件的方法,涉及C#中StreamWriter类操作文件的相关技巧,需要的朋友可以参考下...2020-06-25
ant design中upload组件上传大文件,显示进度条进度的实例
这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29- 举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07