Лучшим подходом здесь, вероятно, является использование файлов с отображенной памятью.
Сначала вам понадобится дескриптор файла, для этого используйте функцию CreateFile
windows API.
Затем передайте это CreateFileMapping
, чтобы получить дескриптор сопоставления файлов. Наконец, используйте MapViewOfFile
, чтобы отобразить файл в память.
Для обработки больших файлов MapViewOfFile
может отображать в память только определенный диапазон, так что вы можете, например, сопоставьте первые 32 МБ, затем используйте UnmapViewOfFile
, чтобы удалить его, затем MapViewOfFile
для следующих 32 МБ и так далее. (РЕДАКТИРОВАТЬ: как было указано ниже, убедитесь, что блоки, которые вы отображаете таким образом, перекрываются кратным 4 КБ, и, по крайней мере, на длину текста, который вы ищете, чтобы вы не пропускали текст, который может быть разделен на границе блока)
Чтобы выполнить фактический поиск, как только (часть) файла отображается в памяти, вы можете сделать копию источника для StrPosLen
из SysUtils.pas (к сожалению, он определен только в разделе реализации и не отображается в интерфейс). Оставьте одну копию как есть и сделайте другую, заменяя Wide
на Ansi
каждый раз. Кроме того, если вы хотите иметь возможность поиска в двоичных файлах, которые могут содержать встроенные #0
файлы, вы можете удалить часть (Str1[I] <> #0) and
.
Либо найдите способ определить, является ли файл ANSI или Unicode, либо просто вызвать версию Ansi и Unicode для каждой сопоставленной части файла.
Как только вы закончили с каждым файлом, обязательно вызовите CloseHandle
сначала для дескриптора сопоставления файлов, а затем для обработки файлов. (И не забудьте сначала позвонить UnmapViewOfFile
).
РЕДАКТИРОВАТЬ:
Большое преимущество использования файлов с отображенной памятью вместо использования, например, TFileStream для чтения файла в память в блоках заключается в том, что байты останутся в памяти только один раз.
Обычно при доступе к файлам сначала Windows считывает байты в файловый кеш ОС. Затем копирует их оттуда в память приложения.
Если вы используете файлы с отображением в памяти, ОС может напрямую отображать физические страницы из файлового кэша ОС в адресное пространство приложения, не делая еще одну копию (сокращая время, необходимое для копирования и наполовину используя память).
Бонусный ответ: вызывая StrLIComp вместо StrLComp, вы можете выполнять поиск без учета регистра.