-
Для быстрой работы с содержимым файла. Например, нужно открыть файл и быстро найти все вхождения определенной подстроки (или определенной последовательности байтов). Пример: формат файла неизвестен, но в файле в разных частях записаны JPEG-и и нужно их все извлечь (ищем FF D8 FF E0)
Спасибо заранее.
-
Читать файл блоками от начала до конца и считать вхождения.
-
Ищем все FF D8, при этом тут же находя концовку FF D9
-
> aka © (10.04.18 10:20) [1]
каков размер блока?
-
> вхождения определенной подстроки (или определенной последовательности > байтов)
Это две разные вещи.
-
> (ищем FF D8 FF E0)
вообще-то, не гарантирует, что это джпег. а так - [1] и никаких библиотек тут не надо.
-
> aka © (10.04.18 10:20) [1] > Читать файл блоками от начала до конца и считать вхождения. >
А если возникнет такая ситуация: читаем блоками на 1024 байт и ищем подстроку "Hello my little world". А она попадает частично в один блок, а частично - в следующий.
Как быть?
-
> читаем блоками на 1024 байт и ищем подстроку "Hello my little world". А она попадает частично в один блок, а частично > - в следующий. > > Как быть?
увеличить блок вдвое. если читать по 2048 байт, то "Hello my little world" точно влазит целиком
-
> А если возникнет такая ситуация: читаем блоками на 1024 > байт и ищем подстроку "Hello my little world". А она попадает > частично в один блок, а частично - в следующий. > > Как быть?
В [4] - ре ж писал, ты либо ищешь строки либо байты. Потому что грубо говоря строка может быть в разных кодировках, отсюда и байтами разными она будет кодироваться
-
> увеличить блок вдвое. если читать по 2048 байт, то "Hello > my little world" точно влазит целиком
Ну тоже не вариант. Например блок заканчивается на "Hello ", следующий начинается на "my little world" в алгоритме это нужно предусмотреть
-
тогда 4096. теперь точно влезет, нутром чую.
-
> тогда 4096.
ну так скорее всего.
-
По одному читать надо. По одному.
-
Читаем 2 блока, ищем. Когда прошли первый блок, грузим третий, прошли второй блок - грузим четвертый и т.д.
-
> Посоветуйте библиотеку для Delphiгм? Не думаю что такие есть... > А если возникнет такая ситуация: читаем блоками на 1024 > байт и ищем подстроку "Hello my little world". А она попадает > частично в один блок, а частично - в следующий. > Как быть?Ватсон? Ну это же элементарно! Вы знаете номер блока? Вы знаете позицию блока? Знаете позицию в которой предположительно найдено совпадение? Просто вычислить новое смещение же! :) > тогда 4096. теперь точно влезет, нутром чую.Академики шутить изволят? С: Увеличение размера блока лишь уменьшают вероятность, но не исключают её. С таким подходом единственный вариант гарантированно исключить попадание на границу - тупо прочитать файл целиком. :3 > Ищем все FF D8, при этом тут же находя концовку FF D9Нюансы для размышлений: FF D8 - вовсе не обязательно начало файла JPEG, FF D9 - вовсе не обязательно конец файла JPEG, FF D8 и FF D9 могут попасться и в самом (остальном) файле и вообще не иметь отношения к JPEG. P.S. http://pda.delphimaster.net/?id=1459559016&n=7
-
> С таким подходом единственный вариант гарантированно исключить > попадание на границу - тупо прочитать файл целиком. :3
и это есть верное решение. и вся библиотека искомая - TFileStream да небольшая оптимизация поиска, реализация которой зависит от условий. Например, если ищем вхождение FF D8 и только его, то нет смысла читать побайтово, можно через один. Если искать строго FF D8 FF E0, то можно читать лишь каждый 4-ый байт, что сокращает время тормознутых файловых операций. А вообще, по поиску паттернов и поиску вообще существует масса литературы. Например, полезно начать с https://www.livelib.ru/author/19753/latest-dzhulian-baknell
-
Верное? Весь файл? Ну допустим что в теории может и так, но на практике появляются проблемы вида - например файл весом 20+ гигов как-то не очень получится прочитать целиком.
TFileStream это не библиотека... В случае с JPEG полагаю сперва надо искать FF, а уже при нахождении делать всякие дополнительные вещи.
-
Писал я утилиту с целевой этой самой == "Нетбук, 1GB DDR2, WinXP" - там если пытаться читать из файла блоками больше 256 метров - уже нехилые проблемы вылазили, а файлы гигабайтами мерялися.
-
> С таким подходом единственный вариант гарантированно исключить > попадание на границу - тупо прочитать файл целиком.
А почему нельзя поблочно читать? если строка поиска не превышает размер блока, то выделяем буфер размером в 2 блока, и читаем туда блоки, бегаем кругами по буферу и ищем... Прочесали один блок, и сразу же на его место грузим очередной.
-
Можно и нужно. Это просто этакой ответ предыдущим человекам, которые силялися всё решить лишь увеличением буфера. (%
Алгоритм желательно изначально проектировать так, чтоб размер буфера можно было легко менять (буквально одним действием, хотя бы константой в коде), и чтоб работало даже если задать размер буфера "1 байт". :3
Зачем два блока? Всё равно заранее не определить понадобится ли второй, а всегда читать по два будет накладным. хотя... Может зависеть от задачи, надо обмозговать.
|