4

我有一组文件大小非常大的文本文件。我不想阅读整个文件。我只对以 . 开头** DATA IMP和结尾的块感兴趣** DATA END。这个块之间的任何数据对我来说都很重要。

但是,此块可能出现在文件的 开头、结尾或文本文件之间。我希望这个阅读过程更快。假设它是在文本文件的开头,它应该和 linux -head 一样快,这对于大文件花费的时间要少得多。

读取这些大文件的最佳方法是什么,所以一旦我得到这个块,我就不必读取文件直到结束?

文件内容示例:(600 MB 或更大)

Dummy text
Dummy text
Dummy text
Dummy text
** DATA IMP
** d
** e
** f
** g
** DATA END
Dummy text
Dummy text
Dummy text
AND SO ON ...

编辑: *好的。我假设数据位于文件顶部,因为我没有其他选项。* 文件内容示例:(600 MB 或更大)

** DATA IMP
** d
** e
** f
** g
** DATA END
Dummy text
Dummy text
Dummy text
Dummy text
Dummy text
Dummy text
AND SO ON ...
4

5 回答 5

2

使用 SplFileObject 类。

首先使用 SplFileObject::fgets 来:

Returns a string containing the next line from the file, or FALSE on error.

像这样的东西

$file = new SplFileObject("file.txt");
while (!$file->eof()) {
   $line = $file->fgets();
   if ($line === 'needle') break;
}

然后,您可以使用$counter变量 to 作为包含针的行的引用。之后,获得您想要的信息非常简单。想找回那条线?还是之后的整个文件?还是在它之前?转到此处并使用SplFileObject静态函数来执行您需要执行的任何其他操作。

于 2013-08-02T06:32:58.497 回答
0

与 grep 等效的 Windows 是 findstr:

在文件中搜索字符串。

查找字符串

于 2014-02-25T01:04:55.000 回答
0

只要文件不在索引、数据库或类似文件中,您就必须遍历整个文件,直到找到** DATA IMP.

另一种选择是,如果该文本位于某个位置,而您的位置则不是。

如果要提取文本:

$file = new SplFileObject("file.txt");

$lines = array();

while (!$file->eof())
{
  $line = $file->fgets();

  if ($line === '** DATA IMP')
    break;
}

$line = $file->fgets();

while($line != '** DATA END')
{
   $lines[] = $line;
   $line = $file->fgets();
}
于 2013-08-02T06:27:59.303 回答
0

我想我将不得不依赖像 grep linux (对于 windows gnu32)这样的外部工具来满足我的特定需求,因为根据我的理解,它比 php 具有更好的性能。

如果您不同意,请添加评论。

于 2013-08-02T06:48:45.623 回答
0

您是否尝试过类似的方法:

<?php
    $raw = shell_exec('grep \'\*\*\' /path/to/file');
    var_dump($raw);
?>

抱歉,刚刚在评论中注意到您使用的是 Windows。我想必须有一个 Windows 版本grep,这可能值得研究。

于 2013-08-02T06:37:44.500 回答