2013-02-18 114 views
3

拉一條線我確定用PHP,但可能還不到一半,因爲一些你們在這裏爲好。PHP從巨大的文本文件

我基本上是試圖找到一種方法,從一個巨大的搶行,我的意思是巨大的文本文件....它基本上關鍵字列表我想行號,但不通過在衆人面前最好要打電話我明白了這一點.....否則顯然可能會損壞我的服務器。

目前即時通訊使用此

$lines = file('http://www.mysite.com/keywords.txt'); 
foreach ($lines as $line_num => $line) { 
    echo "$line_num"; 
} 

這工作,但我確定那裏有一定有一個更好的方式做,以節省usuage因爲這是把整個文件到內存中的,如果我可以簡單地說到PHP給我行數97,將UMM規則....

希望你們能拿出一個解決方案,你要比我聰明:P TY

+1

你爲什麼不使用數據庫來實現呢? – 2013-02-18 11:16:58

回答

2

使用SplFileObject

$file = "test.txt"; 
    $line_number = 1000; 
    $file_obj = new SplFileObject($file); 
    /*** seek to the line number ***/ 
    $file_obj->seek($line_number); 

    /*** return the current line ***/ 
    echo $file_obj->current(); 
+1

您需要先下載文件 – 2013-02-18 11:17:48

+1

這裏面做的是遍歷文件的行。如果沒有在純文本文件中迭代它們,就沒有不可思索的方法來尋找特定的行。這是重要的理解。 – EFraim 2013-02-18 11:20:09

+0

我剛剛嘗試過使用SplFileObject,它的工作非常好.. tnx @ anup-singh – Vikas 2013-02-18 11:20:27

2

如果線的長度是文字和變量,你可以不知道哪個線#97;唯一使它成爲第97位的是前面有96行。

所以,你需要閱讀整個文件到這一點(這是SplFileObject做什麼):

$fp = fopen("keywords.txt", "r"); 
while($line--) 
{ 
    if (feof($fp)) 
     // ERROR: line does not exist 
    $text = fgets($fp, 1024); // 1024 = max length of one line 
} 
fclose($fp); 

但如果你能在每行之前存儲的行號,即該文件是

最有可能的

- start with s1 = 0 and s2 = file length 
- read a keyword and line number at seek position s3 = (s1+s2)/2 (*) 
- if line number is less than desired, s1 = s3; else s2 = s3; and repeat previous step. 
- if line number is the one desired, strip the number from the text and you get the keyword. 

(*),因爲該行:

... 
95 abbagnale 
96 abbatangelo 
97 abbatantuono 
98 ... 

那麼你可以實現一種二進制搜索不會在s#正好開始,你需要與fgets:一個擺脫了僞半關鍵字,第二讀取的行號。當你「關閉」時,閱讀一個更大的塊並將其分成多行會更快。例如,您尋找第170135行並在第170180行讀取:您最好做的是將搜索位置倒回一千字節,讀取一千字節的數據,然後在那裏尋找170135。

或者,如果各行的長度不太相同,則可能需要存儲固定大小的行(這裏「#」實際上應該是空格,並且在行長度中需要對行進行計數終止子,\ n或\ r \ n)的:

abbagnale######### 
abbatangelo####### 
abbatantuono###### 

,然後說每個關鍵字是32個字節,

$fp = fopen("keywords.txt", "r"); 
fseek($fp, 97 * 32, SEEK_SET); 
$text = trim(fgets($fp, 32)); 
fclose($fp); 

會或多或少瞬時的。

如果文件位於遠程服務器上,您仍然需要下載整個文件(直到所需的行),通過在遠程服務器上放置一個「scanner」腳本可以更好地服務運行搜索。然後你可以運行

$text = file_get_contents("http://www.mysite.com/keywords.php?line=97"); 

並以毫秒爲單位獲得你的行。

0

沒有任何方法可以從幾乎任何語言的文件中獲取'行號x',而不必先以某種方式讀取它。畢竟,一條線只是兩個行尾字符之間的東西。雖然從文件中拾取「字符編號x」可以在不加載整個文件的情況下完成(有些困難),但是在沒有加載所有行到x的情況下,無法完成「行號x」(並且在大多數方法中,您需要加載的所有行)

在其中加載的所有行,直到行X中的方法(使用fgets)以下:

$f = fopen('http://www.mysite.com/keywords.txt'); 
$i=97 
$text="" 
while (($text = fgets($f,2048)) !== false && $i>0) { 
     $i-- 
} 
echo $text