摘要:然而,剛進來就擰螺絲的人如果能夠對讀取一個的超大文件有所見解的話,造火箭也是遲早的事兒。其中,用于告知當前文件讀取指針所在位置,可以手動設定文件讀取指針的位置。
作為一名常年深耕curd的PHPer,關注內存那是不可能的,反正apache或者fpm都幫我們做了,況且運行一次就銷毀,根本就不存在什么內存問題。
然而偏偏就有些個不開眼的人把這些個東西當面試題,比如總有刁民用“php讀取一個10G的超大文件”當面試題來問你。當然了,作為一個和我一樣的普普通通的蠢貨,你聽到這個問題的第一瞬間是懵逼,第二瞬間是臥槽,第三瞬間是保持結巴狀態。
“面試造火箭,入職擰螺絲”。然而,剛進來就擰螺絲的人如果能夠對“PHP讀取一個10G的超大文件”有所見解的話,“造火箭”也是遲早的事兒。當前為了能夠來這里“擰螺絲”,還是得先搞定“讀取10G文件”這個問題。
要想讀取10G的文件,首先,你得有個10G的文件
... ...
其實,相對來說也是比較簡單的事情,我們隨便找一個nginx的日志文件,哪怕只有10KB,假設文件名是test.log,然后呢執行" cat test.log >> test.log ",聽我說少年,30秒左右你就該按下ctrl + C了,比如我這里,你們感受一下:
202MB,作為實驗演示,夠意思了。難不成真要造10G的文件?
首先,我們嘗試用php的file函數來作一把死,你們感受一下:
保存為test.php,然后命令行下執行一把,結果如下圖所示:
這句英文的大概意思就是“PHP最大只給每個進程分配了128MB內存,然而你特么張口要202MB?”所以,我們修改一下php配置文件... ...
千萬不要手軟,把這個參數改成1024MB,然后再次執行上面的php腳本:
然后,我們再試試最愛的file_get_contents()函數,結果如下圖:
文件已經一次性全部被載入到內存中并將文件的每一行保存到了一個php數組中,我的機器是10G內存+256G固態硬盤,一次性載入這個202MB的文件file函數用了0.67秒鐘、file_get_contents函數用了0.25秒鐘(看起來file_get_content要比file靠譜的多),不過,敲重點的我們調整了配置文件才可以讀取202MB的文件,如果擺在我們面前的是一個100G的文件呢?或者說,系統提供的php配置最多之給20MB內存而你又無法修改呢?
我們重點是如何在內存有限的機器上讀取體積幾百倍于內存的文件。下面,我們把memory_limit調整成16M,開啟困難模式。
202MB的文件,允許被分配的內存為16MB,所以,總體思路其實也很簡單,就是一點兒一點兒地讀,只要每次讀取的內容小于16MB,那就一定不會有問題,首先我們感受一下一個字符一個字符讀,出場嘉賓是fgetc函數:
運行結果如下圖:
雖然只有給了16M內存,但我們還是成功將202M文件全部讀出來了,只不過這個運行速度是差了那么點兒意思,不大行。不能一個字母一個字母地讀,這次我們一行一行地讀:
運行結果如下圖:
一行一行果然比一個一個字符要快很多,轉念一想吧,系統分配給我們的內存上限是16MB,那我們索性一次讀取一定量容量數據看看,會不會更快:
保存代碼,運行一把,屌了屌了!!!在內存有限的情況下,我們還把時間縮短到了0.1秒!
然后我們考慮將問題升級一下,依然是上述這個202M的文件,這次我們要求讀取倒數后5行的內容,這個問題看起來屌了些許,用原來的fread啥的雖然奏效但總感覺比較愚蠢。所以,現在又得引入全新的函數來解決這個問題:ftell和fseek。其中,ftell用于告知當前文件讀取指針所在位置,fseek可以手動設定文件讀取指針的位置。我建議大家去手冊上重點觀摩一下fseek函數:點擊這里。
0 ){ while( $ch != " " ){ fseek( $fp, $pos, SEEK_END ); $ch = fgetc( $fp ); $pos--; } $ch = ""; $content .= fgets( $fp ); $line--; } echo $content; exit;其中test1.log文件的內容如下:
aa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffff bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffff bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffff bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffff bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffff bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffff 1111111111 2222222222保存文件并運行,結果如下圖所示:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29736.html
摘要:在中,會為每個不同的用戶生成一個隨機的,每個人擁有的都是不同的。值得注意的是,過期了不代表這個文件會馬上被垃圾回收機制刪除掉,還是有可能會殘存一段時間的。 原文地址:https://t.ti-node.com/thread/... 這基本上算是個老舊的話題了,幾乎所有phper在第一次面試的時候都會被問到關于session的問題,如果不出意外,往往是如下三板斧: php的sessi...
摘要:這篇筆記主要解決這么幾個問題如何使用超低內存快速遍歷數以萬計的目錄文件如何使用超低內存快速讀取幾百甚至是級文件順便解決哪天我忘了可以通過搜索引擎搜到我自己寫的筆記來看看。 這不是一篇教程,這是一篇筆記,所以我不會很系統地論述原理和實現,只簡單說明和舉例。 前言 我寫這篇筆記的原因是現在網絡上關于 PHP 遍歷目錄文件和 PHP 讀取文本文件的教程和示例代碼都是極其低效的,低效就算了,有...
摘要:場景和痛點說明今天因為一個老同學找我,說自己公司的物流業務都是現在用處理,按月因為數據量大,一個差不多有百萬數據,文件有接近,打開和搜索就相當的慢聯想到場景要導入數據,可能數據量很大,這里利用常用的一些方法比如會常有時間和內存限制問題下面我 場景和痛點 說明 今天因為一個老同學找我,說自己公司的物流業務都是現在用excel處理,按月因為數據量大,一個excel差不多有百萬數據,文件有接...
摘要:能異步地發送任意數據的技術稱為,表示異步的和。若你使用,使用發送表單還會影響同源策略,并導致內容被發送到一個無法訪問的中。但要手動發送二進制數據的話,還有很多額外工作要做。用來發送二進制是很直接的,使用方法就好了。 系列文章說明 原文 在[發送表單數據]()一文中,HTML表單可以聲明式地發送一個HTTP請求。但表單也可以用JavaScript來準備一個HTTP請求。本文將探索如何...
閱讀 1463·2021-11-24 09:39
閱讀 1781·2021-11-22 15:25
閱讀 3732·2021-11-19 09:40
閱讀 3291·2021-09-22 15:31
閱讀 1294·2021-07-29 13:49
閱讀 1201·2019-08-26 11:59
閱讀 1313·2019-08-26 11:39
閱讀 927·2019-08-26 11:00