2013-02-18 78 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