Поиск в содержимом файла

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 8:32

Добрый день.
Пишу класс, для программы, который должен определять, при помощи какого инсаллятора собран дистрибутив программы.
Путем просмотра exe-шников, понял, что для этой цели можно использовать поиск по содержимому файла (тупо в редакторе открываем exe-шник и ищем например inno setup. Если такая запись есть, значит для создания инсталяшки использовался inno setup).

Решил сделать так: Читал exe-файл оператором Open построчно. Каждую строку писал в массив. Затем из массива сравнивал каждую строку с предполагаемым значением. Все должно было быть хорошо, НО, как выяснилось позже, при построчном чтении exe-файла он забирал его одной строчкой (ну, кто бы сомневался, сразу не подумал об этом) и соответственно в переменной оказывался только незначительный кусок файла.

Вопрос: Каким образом реализовать в данном случаи поиск значения в файле? Подозреваю что нужно читать файл не построчно, а посимвольно. Но тогда есть вероятность, что искомое значение будет разбито на 2 части и поиск завершится крахом.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Поиск в содержимом файла

Сообщение alibek » 20.09.2011 (Вт) 8:36

1. Читай блоками по 64 Кб.
2. При чтении следующего блока сдвигай указатель назад, на число символов искомой строки.
Lasciate ogni speranza, voi ch'entrate.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 8:39

спс. Блин, все просто :alien:

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 12:21

Блин, все не просто :(

Код: Выделить всё
Dim TextLine As String * 2048
Open "C:\1.exe" For Input As #1
Do While Not EOF(1)   
    Line Input #1, TextLine
MsgBox TextLine
Loop
Close #1


Читается только первая строка размером 2048 байт. А дальше?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 20.09.2011 (Вт) 12:41

Какого фига Line Input? Get надо использовать.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 13:28

На такой код нарекания есть?

Код: Выделить всё
word = "Inno Setup"

Dim TextLine As String * 2048
Open "C:\1.exe" For Binary As #1
Do While Not EOF(1)
i = i + 1
    Get #1, (i * 2048) - Len(word), TextLine
   
    If InStr(1, TextLine, word) > 0 Then MsgBox word
   
Loop
Close #1

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 20.09.2011 (Вт) 13:31

Конечно есть. Абсолютно отсутствует смысл в отнимании Len(word) это раз, и два: если «фраза» окажется на границе двух кусков, то будет облом.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 13:34

Хакер писал(а):Конечно есть. Абсолютно отсутствует смысл в отнимании Len(word) это раз, и два: если «фраза» окажется на границе двух кусков, то будет облом.


Как раз для этого и вставлено
Код: Выделить всё
- Len(word)
. Если не ошибаюсь, это должно сдвинуть указатель назад, на число символов искомой строки, как советовал alibek. Если ошибаюсь, поправь.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 20.09.2011 (Вт) 13:43

Блин, ну думать то хоть чуть-чуть нужно и пытаться подставлять какие-то значения.
В первый раз i будет равно 1, и будет прочитан диапазон 2038:4086.
Во второй раз i будет 2, и будет прочитан диапазон 4086:6134.

И так далее.
Начало файла (диапазон 1:2037) не обрабатывается вообще, и никаким образом не предусмотрен случай, когда фраза лежит на границе блоков.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 20.09.2011 (Вт) 13:49

И вообще это крайне глупо читать куски по 2 кб в буфер и искать в кусках, а потом ещё заботиться о возможном расположении фразы на границе кусков. Спроецируй весь файл целиком в память и найди нужную строчку одним выстрелом.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 13:49

а если файл весит гиг? И что ты скажешь по поводу - Len(word)?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 20.09.2011 (Вт) 14:03

kuhtiov писал(а):а если файл весит гиг?

То в случае проекции ничего страшного из этого не произойдёт.

kuhtiov писал(а):И что ты скажешь по поводу - Len(word)?

Я уже сказал, ты написал глупое выражение, смысл которого вряд ли сам понимаешь. Ты просто сдвинул границы блоков на десять байтов назад. А читаемые блоки как были неперекрывающимися, так неперекрывающимися и остались.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 15:57

А как можно загрузить файл целеком? Ведь будет ошибка, файл та не пару метров.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Поиск в содержимом файла

Сообщение ger_kar » 20.09.2011 (Вт) 20:48

А можно не парится и реализовать такой алгоритм поиска:
Считываем файл побайтно и сравниваем с кодом первого символа в строке поиска, при совпадении сравниваем со вторым и так далее, при первом обломе если не дошли до конца сравниваемой сроки, делается вывод, что это не тот кусок и продолжаем дальше. Если находит искомый кусок останавливаем поиск. В плане производительности конечно такой алгоритм не очень, зато все очень просто и к тому-же если кусок находится в начале, а я думаю, что в данном случае это так, то и файл до конца читать не надо.
Бороться и искать, найти и перепрятать

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 20.09.2011 (Вт) 21:24

ger_kar писал(а):А можно не парится и реализовать такой алгоритм поиска:
Считываем файл побайтно и сравниваем с кодом первого символа в строке поиска, при совпадении сравниваем со вторым и так далее, при первом обломе если не дошли до конца сравниваемой сроки, делается вывод, что это не тот кусок и продолжаем дальше. Если находит искомый кусок останавливаем поиск. В плане производительности конечно такой алгоритм не очень, зато все очень просто и к тому-же если кусок находится в начале, а я думаю, что в данном случае это так, то и файл до конца читать не надо.



Это конечно вариант, но получится многастроккода и работать такой алгоритм будет значительно медленнее (ИМХО). Так все таки, как прочитать большой файл целеком?

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Поиск в содержимом файла

Сообщение ger_kar » 20.09.2011 (Вт) 21:36

kuhtiov писал(а):Это конечно вариант, но получится многастроккода и работать такой алгоритм будет значительно медленнее
Наоборот, все будет предельно просто и лаконично, а скорость работы в случае если искомый кусок будет находится до середины файла, будет вполне нормальной. Причем, если считывать целиком большой файл в память, а потом его вторично сканировать с целью поиска, да еще если по причине нехватки оперативной памяти, будет активно задействован файл подкачки, то вряд ли такой метод окажется быстрее.
Бороться и искать, найти и перепрятать

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Поиск в содержимом файла

Сообщение iGrok » 20.09.2011 (Вт) 22:03

Что делать, что делать. Читать. Думать.

Хакер же написал, что делать. Мэппинг делать, и не извращаться. Читаться целиком в память он при этом не будет (или будет, это уже винда решит, ей виднее), но работать ты с ним сможешь так, как будто он целиком в памяти.

Либо делать как написал Алибек. Только не так, как ты "сделал", а так, как он написал. Хакер указал в чём разница.

ger_kar, это при побайтном-то чтении из файла скорость приемлемой будет?! Попробуй на гиговом файле, ради интереса.. Так, чтобы искомая строка где-нибудь в середине файла была.
А потом то же самое, но с мэппингом или чтением по 64к. И замерь скорость.
label:
cli
jmp label

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 21.09.2011 (Ср) 3:32

Мэппинг? Можно ссылку? Только не http://google.ru :)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 21.09.2011 (Ср) 5:43

ger_kar писал(а):Считываем файл побайтно...

Изображение

kuhtiov писал(а):А как можно загрузить файл целеком? Ведь будет ошибка, файл та не пару метров.

Зачем придумывать какую-то ерунду и её спрашивать?
Есть в Windows и других ОС замечательная техника, лучше которой (по прозрачности и эффективности) ты ничего не придумаешь, даже если будешь трижды гением.

Ты проецируешь файл в виртуальное адресное пространство, при этом весь файл не читается в физическую память. Вообще ни один файл изначально не читается в физическую память. В физическую память будет читаться фрагменты файла, размером кратные размеру страницу (4 кб в общем случае), причём читаться они будут автоматически, по мере необходимости. С какой областью файла сейчас работаешь, те куски автоматически и подгружаются в физ. память, а лишние выгружаются. Какие выгружать и как подгружать определяет ОС на основе своей информации о всей ситуации, и обеспечивает максимальную производительность.

Теперь кое-что ещё. Когда ты читаешь фрагменты файл в буфер, не важно какого размера будет буфер, буфер занимает место в файле подкачки. Всегда занимает. Объём всей памяти, которая может быть выделена всем программам в сумме ограничен размером файла подкачки. Поэтому выделили буфер, размером 64 кб, другим программам достанется на 64 кб меньше.

А если ты проецируешь файлы, то хоть гигабайт спроецируй, файл подкачки не тратится при этом вообще.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Поиск в содержимом файла

Сообщение ger_kar » 21.09.2011 (Ср) 5:56

iGrok писал(а):ger_kar, это при побайтном-то чтении из файла скорость приемлемой будет?! Попробуй на гиговом файле, ради интереса.
А мне кстати очень интересно, вон даже Хакер от мой идеи прослезился ;) . Но просто замерять скорость мне не интересно, а интересно именно сравнить, поэтому к вечеру выложу код и жду соответственно кода от kuhtiov, а потом и сравним ;) . Что-бы условия были одинаковыми файл я думаю надо будет брать, такой, который заведомо есть на компе у каждого, ну или создать его, по одному методу. Так что до вечера :)
Бороться и искать, найти и перепрятать

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Поиск в содержимом файла

Сообщение alibek » 21.09.2011 (Ср) 8:04

ger_kar писал(а):Считываем файл побайтно

Предлагаю считывать побитно, это будет гораздо круче.
Lasciate ogni speranza, voi ch'entrate.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Поиск в содержимом файла

Сообщение iGrok » 21.09.2011 (Ср) 8:13

kuhtiov писал(а):Мэппинг? Можно ссылку? Только не http://google.ru :)

viewtopic.php?f=28&t=25202
label:
cli
jmp label

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 21.09.2011 (Ср) 8:16

ger_kar писал(а):А мне кстати очень интересно, вон даже Хакер от мой идеи прослезился ;).


Хакер не прослезился. У Хакера даже слов не нашлось. По видимому не знал как корректнее прокомментировать. Мне кажется это сравнимо с перетаскиванием воды из бочки. Или таскать воду ведрами (в данном случаи вообще наперстками) или перенести бочку за раз. Как-то так.
Хорошо, самому любопытно узреть разницу в производительности. К вечеру постараюсь выложить код.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 21.09.2011 (Ср) 8:44

kuhtiov писал(а):Мне кажется это сравнимо с перетаскиванием воды из бочки. Или таскать воду ведрами (в данном случаи вообще наперстками) или перенести бочку за раз. Как-то так.

Если вёдрами — это твой подход с буфером, а бочкой разом — мой подход с проекцией всего файла разом, то аналогия полностью провальная.

Это значит, что либо ты не читал, либо ты не понял вот этого. Читаем и понимаем ещё раз:
Хакер писал(а):Ты проецируешь файл в виртуальное адресное пространство, при этом весь файл не читается в физическую память. Вообще ни один файл изначально не читается в физическую память. В физическую память будет читаться фрагменты файла, размером кратные размеру страницу (4 кб в общем случае), причём читаться они будут автоматически, по мере необходимости. С какой областью файла сейчас работаешь, те куски автоматически и подгружаются в физ. память, а лишние выгружаются. Какие выгружать и как подгружать определяет ОС на основе своей информации о всей ситуации, и обеспечивает максимальную производительность.


Ещё раз: когда ты спроецируешь весь файл в целиком, он по прежнему будет читаться с диска маленькими порциями. Но дробить его на порции и читать их с диска будет уже не твой код, а операционная система. И в любом случае делать она это будет эффективнее, чем твой код.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 21.09.2011 (Ср) 9:58

Хакер, я понял тебя. Про бочку, ведра и наперсток я отвечал ger_kar-у. Сейчас как раз ищу "кран для бочки", пытаясь разобраться с кирпичом http://bbs.vbstreets.ru/viewtopic.php?f=28&t=25202

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 21.09.2011 (Ср) 10:15

Помогите разобраться с этим классом http://bbs.vbstreets.ru/viewtopic.php?f=28&t=25202

Код: Выделить всё
Dim CSharedFileF As New CSharedFile
    MsgBox CSharedFileF.CreateFromFile("c:\1.exe", "myfile")
   
    MsgBox CSharedFileF.OpenFileMap("myfile")
   
    MsgBox CSharedFileF.MapOfView


Область памяти возвращает, тут все просто. А как теперь работать с файлом? OpenFileMap?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 21.09.2011 (Ср) 10:42

Open вообще не нужен.

Open был бы нужен, если бы было два разных (или одинаковых процесса), желающих получить общий регион памяти.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 21.09.2011 (Ср) 10:56

Я больше не вижу вариантов в классе для работы со спроецированным файлом. Не понял назначение FlushOfView, но мне кажется тоже не мой вариант. Если честно, я ожидаю что я получу переменную (или что-то в этом роде), с которой я смогу выполнить нужный мне поиск, но что-то мне подсказывает, что я не в ту сторону смотрю. Поправьте.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Поиск в содержимом файла

Сообщение Хакер » 21.09.2011 (Ср) 11:00

Метод-функция MapOfView возвращает адрес начала файла. Вот ищешь начиная с этого места и до конца минус длина фразы плюс один.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kuhtiov
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 03.08.2006 (Чт) 5:31

Re: Поиск в содержимом файла

Сообщение kuhtiov » 21.09.2011 (Ср) 11:07

Хакер писал(а):Метод-функция MapOfView возвращает адрес начала файла. Вот ищешь начиная с этого места и до конца минус длина фразы плюс один.


То что мне возвращается адрес начала файла, я понимаю. Как прочитать "буквы" из памяти?
и к стати, почему +1?

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 88

    TopList