|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Янв 29, 2004 10:22:06 Имею проблему: есть большой файл, в котором надо найти строку и заменить. Вопрос: как это сделать? С заменой проблем нет, а вот с поиском есть... Ничего кроме чтения в буфер до нужного места в голову не лезет, но метод совсем не дзенский... Дополнительная сложность в том, что все это надо сделать на АПИ. Средствами ДОСа я бы это сделал с легкостью, но вот под винду я такое только на сях когда-то делал и то с помощью стандартных функций... Если тема уже поднималась, дайте ссылку, а то с моей связью поиск грузиться отказался... :( |
|
|
Дата: Янв 29, 2004 11:08:20 Вот откопал функцию SetFilePointer. Позиционирует указатель в файле. Вобщем, решение найдено, но может кто-то предложит более интересный метод поиска и замены пары байт в файле? |
|
|
Дата: Янв 29, 2004 11:09:06 dz 3BePIOra Позиционирование - SetFilePointer/SetFilePointerEx. Можно использовать mmf, тогда работа с файлом становится похожей на работу с массивом, т.е. произвольный доступ. |
|
|
Дата: Янв 29, 2004 12:48:31 mmf рулит, если файл не слиииииишком большой, к тому же, может быть быстрее, чем ReadFile.. Если файл очень большой, то поможет кольцевой буфер (или очередь?), туда можно хоть читать, хоть отображать. Логика поиска усложнится совсем немного. На всякий случай пример использования mmf с поиском и заменой строки (не меньше 2-х байт): .DATA filename DB "HNY.lst",0 findbytes DB "DIRECTINPUT_VERSION " ;; what is to find findbytessize equ $-findbytes replacebytes DB "DiReCT1NPUT_VERS10n!!" ;; what is to put over .CODE the proc invoke CreateFile, offset filename,GENERIC_READ or GENERIC_WRITE,0,0,OPEN_EXISTING,0,0 .if EAX != INVALID_HANDLE_VALUE push EAX ;; file handle invoke CreateFileMapping,EAX,0,PAGE_READWRITE,0,0,0 .if EAX push EAX ;; file-mapping object handle invoke MapViewOfFile,EAX,FILE_MAP_ALL_ACCESS,0,0,0 .if EAX push EAX ;; we've got address of file data in EAX. let's use it ;) mov EDI, offset findbytes+1 L: mov bl, [EDI] inc EAX cmp [EAX], bl jnz L mov ECX, 0 L2: mov bl, [EDI+ECX] cmp [EAX+ECX], bl jnz L inc ECX cmp ECX, findbytessize-1 jnz L2 ;; we found it inc ECX lea EDI, [EAX-1] mov ESI, offset replacebytes rep movsb ;; release used objects call UnmapViewOfFile ;; parameter is already on stack call CloseHandle ;; parameter is already on stack call CloseHandle ;; parameter is already on stack .endif .endif .endif the endp |
|
|
Дата: Янв 30, 2004 04:20:50 S_T_A_S_ Какие проблемы у mmf с большими файлами? Наверное ты имеешь ввиду проблемы программиста? |
|
|
Дата: Янв 31, 2004 07:12:40 S_T_A_S_ В данном примере осуществляется поиск "IRECTINPUT_VERSION " вместо "DIRECTINPUT_VERSION " :-) А что если этой строки вообще нет в файле? Страшно представить. :-) Правильнее добавить GetFileSize перед CreateFileMapping. |
|
|
Дата: Янв 31, 2004 07:32:26 S_T_A_S_ + исходный файл может иметь размер больше 2Gb (на NTFS), тогда маппировать надо частями. |
|
|
Дата: Фев 2, 2004 13:23:56 · Поправил: S_T_A_S_ q_q Наверное ты имеешь ввиду проблемы программиста? Да, совершенно верно :) Тоже относительно + (я писал про буфер ^^, хотя не знаю правильный термин) Quantum Новый глюк лучше старых двух.. Я чуток не тот листинг запостил.. По поводу "нет строки" тоже верно. У меня упрощеный вариант, т.е. условие - строка заведомо есть |
|
|
Дата: Май 27, 2004 17:06:15 · Поправил: Безпощадный даос "Лучше поздно чем некогда" :) Чё-то у меня этот код не хочет работать.. :( может подскажите как скомпилить, чтоли :)) .486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
AppName db "xz",0
Sovpadaet db "Совпадает",0
NeSovpadaet db "НЕ совпадает",0
filename db "xz.txt",0
text db "Text.."
findbytes db "IRECTINPUT_VERSION "
findbytessize equ $-findbytes
.code
start:
invoke CreateFile, offset filename,GENERIC_READ or GENERIC_WRITE,0,0,OPEN_EXISTING,0,0
.if eax != INVALID_HANDLE_VALUE
push eax
invoke CreateFileMapping,EAX,0,PAGE_READWRITE,0,0,0
.if eax
push eax
invoke MapViewOfFile,EAX,FILE_MAP_ALL_ACCESS,0,0,0
.if eax
push eax
mov edi, offset findbytes+1
L: mov bl, [edi]
inc eax
cmp [eax], bl
jnz L
mov ecx, 0
L2: mov bl, [edi+ecx]
cmp [eax+ecx], bl
jnz L
inc ecx
cmp ecx, findbytessize-1
jnz L2
inc ecx
lea edi, [eax-1]
mov esi, offset text
rep movsb
call UnmapViewOfFile
call CloseHandle
call CloseHandle
.endif
.endif
.endif
invoke ExitProcess,eax
end start
p.s.Оказывается, моё ламерство не знает границ :) |
|
|
Дата: Май 28, 2004 05:51:28 Flasher Всё это весма странно. Мой код вполне рабочий, хотя и несколько глючный :). Замечание Quantum вполне уместно - offset findbytes+1 указывает на 2й байт строки. |
|
|
Дата: Май 28, 2004 05:56:38 Flasher В чем выражается "не хочет работать"? + вызывать CloseHandle надо между .endif'ами. |
|
|
Дата: Май 28, 2004 06:15:41 S_T_A_S_ > Мой код вполне рабочий, хотя и несколько глючный :) Уж лучше тогда мой код использовать ;-) может искать строку даже если часть байт в ней будет не совпадать с искомой, примерчик где-то валяется в форуме, его немножко подправить и вперед, ищет достаточно быстро. Кстати используется мной в SignFinder'е для link.exe ;-) |
|
|
Дата: Май 28, 2004 09:00:53 Компилю вышенаписанный код, запускаю - даёт ошибку Offset: 00001052 мож мои include - косячные? Asterix, http://www.wasm.ru/forum//index.php?action=vthread&forum=4&topic=4489&page=2 ? |
|
|
Дата: Май 28, 2004 09:02:05 Компилю вышенаписанный код, запускаю - даёт ошибку Offset: 00001052 мож мои include - косячные? Asterix, http://www.wasm.ru/forum//index.php?action=vthread&forum=4&topic=4489&page=2 ? |
|
|
Дата: Май 28, 2004 09:06:25 Flasher Компилю ... даёт ошибку Offset: 00001052 Чем? У меня в masm'е без проблем. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.418 |