· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Позиционирование в файле

. 1 . 2 . >>

Посл.отвђт Сообщен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'е без проблем.

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.418