如何使用PHP在大文件中查找文本?

时间:2016-03-04 16:31:04

标签: php search large-files

我需要检测包含我的字符串的文件。文件大小可以大于4GB。我不能简单地使用像file_get_contents()这样的工具,因为它试图将文件放入RAM中。

我该怎么做?使用标准PHP?使用elasticsearch或其他外部搜索引擎?

3 个答案:

答案 0 :(得分:4)

如果您有基于Linux的计算机,则可以使用grep命令:

shell_exec( 'grep "text string to search" /path/to/file');

作为输出,您将拥有包含文字的所有行。

here你可以找到一个使用grep的简单教程!

如果您需要查找目录中包含某些文本的所有文件,可以使用

shell_exec( 'grep -rl "text string to search" /path/to/dir' );

r代表"递归",所以它会查找每个文件

l代表"显示文件名"

因此,您将拥有所有文件名(每行一个)。

答案 1 :(得分:2)

file_get_contents将整个文件的内容作为变量返回。在你的情况下,这意味着它将尝试创建4GB变量,耗尽允许的内存。

尝试使用fopenfgets。这将允许您以较小的块处理文件。

试一试! :)

答案 2 :(得分:2)

你可以使用这样的东西。这根本没有优化或测试,可能有一些未被注意到的bug,但你应该明白这个想法:

function findInFile($file_name, $search_string, $chunk_size=1024) {
    // Because we are going to look back one chunk at a time,
    // having $search_string more than twice of chunks will yield
    // no result.
    if (strlen($search_string) > 2 * $chunk_size) {
        throw new \RuntimeException('Size of search string should not exceed size of chunk');
    }
    $file = new \SplFileObject($file_name, 'r');
    $last_buffer = '';
    while (!$file->eof()) {
        $chunk = $file->fread($chunk_size);
        $buffer = $last_buffer . $chunk;
        $position_in_buffer = strstr($buffer, $search_string);
        if ($position_in_buffer !== false) {
            // Return position of string in file
            return
                $file->ftell() - strlen($chunk) + $position_in_buffer
            ;
        }
        $last_buffer = $chunk;
    }
    return null;
}