我需要检测包含我的字符串的文件。文件大小可以大于 4GB。我不能简单地使用file_get_contents()
这样的工具做到这一点,因为它试图将文件放入 RAM 中。
我该怎么做?使用标准 PHP?使用弹性搜索或其他外部搜索引擎?
如果你有一台基于 Linux 的机器,你可以使用 grep 命令:
shell_exec( 'grep "text string to search" /path/to/file');
作为输出,您将拥有包含文本的所有行。
在这里,您可以找到使用grep的简单教程!
如果您需要查找目录中包含某些文本的所有文件,您可以使用
shell_exec( 'grep -rl "text string to search" /path/to/dir' );
r代表"递归",所以它会在每个文件中查找
l 代表"显示文件名"
因此,您将拥有所有文件名(每行一个)。
你可以
使用这样的东西。这根本没有经过优化或测试,并且可能有一些我没有注意到的错误,但你应该明白:
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;
}
file_get_contents
将整个文件的内容作为变量返回。在您的情况下,这意味着它将尝试创建 4GB 变量,这会耗尽允许的内存。
尝试使用 fopen 和 fgets。这将允许您以较小的块处理文件。
试一试!:)