1

Тема: AHK: Как в НЕтекстовом файле заменить строку?

Пытаюсь заменять определённую строку в нетекстовых файлах. Читаю файл с помощью loop,Read,/файл/. 

Строка находится, но даже при выводе A_LoopReadLine через MsgBox отображается не вся. Наверное это правильно, но в самой A_LoopReadLine строка хранится не вся, да и не каждая похоже. По крайней мере, при попытке записать все A_LoopReadLine в новый файл, некоторые строки вообще выпадают.

Можно найти строку с помощью FileReadLine, поскольку её номер известен, но как создать новый файл, который будет отличаться от старого только этой строкой?

2

Re: AHK: Как в НЕтекстовом файле заменить строку?

А что такое строка, если файл не текстовый?

3 (изменено: Next, 2013-09-16 20:11:04)

Re: AHK: Как в НЕтекстовом файле заменить строку?

Хорошо бы и самому это знать.    Увы.

Но как-то loop,Read, находит какие-то определённые куски, которые помещает в A_LoopReadLine. По какому принципу он это делает - для меня загадка.

С помощью FileReadLine я тоже смог отыскать нужный мне участок, пройдясь по всему файлу. Там похоже принцип другой, поскольку "строка" с нужным участком у FileReadLine начинается раньше. По крайней мере в том виде, что доступен для просмотра через MsgBox.

4

Re: AHK: Как в НЕтекстовом файле заменить строку?

В практически любом файле можно найти произвольные части, доступные для просмотра в текстовом формате, даже в EXE-файле. Это ни о чем не говорит, для чтения и обработки таких файлов нужно использовать двоичный режим, чтобы обрабатывать нечитаемые символы.

5

Re: AHK: Как в НЕтекстовом файле заменить строку?

Можете предложить готовый алгоритм или код, который лучше всего подойдёт для поиска определённого фрагмента длиной до 100 символов в файлах размером 50-100КБ?

6

Re: AHK: Как в НЕтекстовом файле заменить строку?

В нетекстовых файлах, вообще говоря, нет символов, там просто байты. Что конкретно вы ищете и как искомое задаёте?

7

Re: AHK: Как в НЕтекстовом файле заменить строку?

Я ищу участок заключённый между известными мне группами байт.  Допустим между  "123 125 127 130"  и  "255 253 251 250"  находится искомые байты.  Мне нужно их найти, прочитать, на их место вписать другие. Всё остальное оставить без изменений.

8

Re: AHK: Как в НЕтекстовом файле заменить строку?

А размер этого участка известен?

9

Re: AHK: Как в НЕтекстовом файле заменить строку?

Всегда разный, но границы известны.  Допустим всегда от  10 до 100 байт. В файлах весом от 50 до 100Кб.

10

Re: AHK: Как в НЕтекстовом файле заменить строку?

+ ОФФ

YMP
Видимо частично будет ответ, и на этот вопрос.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: Как в НЕтекстовом файле заменить строку?

А куда девать прочитанные байты? Вы их будете как-то смотреть и на их основе принимать решение о перезаписи, или перезапись производится в любом случае? Данные для перезаписи тоже в виде "255 253 251 250"?

12

Re: AHK: Как в НЕтекстовом файле заменить строку?

YMP пишет:

А куда девать прочитанные байты?

   Из искомого блока - вносить в переменную, анализировать.


Вы их будете как-то смотреть и на их основе принимать решение о перезаписи

  Да.

Данные для перезаписи тоже в виде "255 253 251 250"?

  Искомый участок состоит из цифр и латинских символов и заменятся будет такими же символами. В каком виде его считывать и каком потом вписывать - не важно. Важно получить его, обработать и при необходимости вписать нужное на его место.

13 (изменено: serzh82saratov, 2013-09-17 21:14:01)

Re: AHK: Как в НЕтекстовом файле заменить строку?

Я предполагаю так:
С помощью RawRead прочитать и преобразовать байты в десятичные числа через пробел (например) и записать в переменную. Найти искомое как текст, представить записываемое как десятичные байты (учитывая кодировку), заменить этим нужный кусок в переменной. RawWrite - записать файл по новому (учитывая кодировку, и новый размер).

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

14 (изменено: Next, 2013-09-17 23:57:51)

Re: AHK: Как в НЕтекстовом файле заменить строку?

Спасибо, поищу что за операторы.



PS. У меня кажется дежа вю...  http://forum.script-coding.com/viewtopic.php?id=8453

15 (изменено: serzh82saratov, 2013-09-17 21:40:28)

Re: AHK: Как в НЕтекстовом файле заменить строку?

File Object

Для оформления ссылок используйте тег url.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16 (изменено: serzh82saratov, 2013-09-17 23:43:31)

Re: AHK: Как в НЕтекстовом файле заменить строку?

С помощью RawRead прочитать и преобразовать байты в десятичные числа через пробел (например) и записать в переменную.

Долгое занятие получается:


SetBatchLines -1
File := FileOpen(FileName, "r")  
file.RawRead(buf, file.length)

Loop, % file.length 
    hex .= NumGet(buf, A_Index - 1, "UChar") " "
MsgBox, %hex%
file.Close()
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

17

Re: AHK: Как в НЕтекстовом файле заменить строку?

Next пишет:

PS. У меня кажется дежа вю...  http://forum.script-coding.com/viewtopic.php?id=8453

Ну да, тоже было ощущение повтора темы. Кстати, задать вопрос и исчезнуть — не слишком красиво выглядит.

В каком виде его считывать и каком потом вписывать - не важно. Важно получить его, обработать и при необходимости вписать нужное на его место.

Ну как же не важно? Для кода сугубая конкретика нужна. Если байты задаются и отображаются как "255 255 255", будет один код, если иначе — другой. Если перезапись идёт сразу — один код, если какие-то манипуляции (какие?) со считанным и на их основе перезапись — другой. Получить, обработать и вписать — это слишком общая формулировка. Для человека она годится. Откроет файл в хекс-редакторе, переведёт калькулятором десятичное отображение искомых байтов в шестнадцатеричное, найдёт глазами эти байты, вобьёт что нужно с клавиатуры и сохранит файл. Но программа за вас додумать и сообразить ничего не может. Вы должны всё максимально конкретизировать, все детали.

Вот сейчас вам какой пример кода хотелось бы увидеть? Допустим, это будет функция. Что и в каком виде она должна принимать, что и в каком виде возвращать? Что должна делать в случае неудачи? Максимально конкретно можете описать?

18

Re: AHK: Как в НЕтекстовом файле заменить строку?

Из моей теории, получился такой вот смешной код, вроде даже рабочий:


SetBatchLines -1
FileName =  
FileName2 =

File := FileOpen(FileName, "r")  
file.RawRead(buf, Length := file.length)
file.Close()

Loop % Length
    hex .= NumGet(buf, A_Index - 1, "UChar") " " 
 
 ; Здесь делаем нужные изменения в строке десятичных байтов, как в тексте
 ; Т.е. изменяем переменную "hex"

RegExReplace(hex, A_Space, "", NewLength) ; Узнаём новое количество байтов по кол-ву пробелов в изменённой строке
VarSetCapacity(buf2, NewLength, 0)

SetFormat, IntegerFast, H
Loop, parse, hex, %A_Space% 
    NumPut(A_LoopField + 0, buf2, A_Index - 1, "UChar")  

file := FileOpen(FileName2, "w")
file.RawWrite(buf2, NewLength)
file.Close()
MsgBox

Тут создаётся новый изменённый файл, для перезаписи исходного файла нужно внести небольшие изменения.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

19 (изменено: Next, 2013-09-18 12:02:25)

Re: AHK: Как в НЕтекстовом файле заменить строку?

YMP пишет:

Ну да, тоже было ощущение повтора темы. Кстати, задать вопрос и исчезнуть — не слишком красиво выглядит.

  Посыпаю голову пеплом. Ничего не понял в коде, решил попробовать разобраться позже, закрутился, потом вынужден был совсем отвлечься и благополучно забыл. Извиняюсь.

Ну как же не важно? Для кода сугубая конкретика нужна. Если байты задаются и отображаются как "255 255 255", будет один код, если иначе — другой. Если перезапись идёт сразу — один код, если какие-то манипуляции (какие?) со считанным и на их основе перезапись — другой. ... Вы должны всё максимально конкретизировать, все детали?

      В каком виде бы я не получил нужную строку, мне нужно привести её в формат латинских букв и цифр, потом обработать и если для записи надо, опять можно преобразовать в  "255 255 255". Это можно сделать в подпрограмме которая уже практически существует, а потом вернуться в участок кода считывания/записи.


Вот сейчас вам какой пример кода хотелось бы увидеть? Допустим, это будет функция. Что и в каком виде она должна принимать, что и в каком виде возвращать? Что должна делать в случае неудачи? Максимально конкретно можете описать?

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

20

Re: AHK: Как в НЕтекстовом файле заменить строку?

serzh82saratov пишет:

Из моей теории, получился такой вот смешной код, вроде даже рабочий

Спасибо! Попробую разобраться.

21 (изменено: serzh82saratov, 2013-09-18 17:17:58)

Re: AHK: Как в НЕтекстовом файле заменить строку?

Нашёл излишнее связанное с NumPut:


File := FileOpen(FileName, "r"), File.Pos := 0
File.RawRead(buf, Length := file.length)
File.Close()

Loop % Length
    hex .= NumGet(buf, A_Index - 1, "UChar") " " 
 
 ; Здесь делаем нужные изменения в строке десятичных байтов, как в тексте
 ; Т.е. изменяем переменную "hex"

RegExReplace(hex, A_Space, "", NewLength) ; Узнаём новое количество байтов по кол-ву пробелов в изменённой строке
VarSetCapacity(buf2, NewLength, 0)
 
Loop, parse, hex, %A_Space% 
    NumPut(A_LoopField, buf2, A_Index - 1, "UChar")  

File := FileOpen(FileName2, "w"), File.Pos := 0
File.RawWrite(buf2, NewLength)
file.Close()
MsgBox
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

22

Re: AHK: Как в НЕтекстовом файле заменить строку?

serzh82saratov
Подозреваю, что каждый байт должен отображаться тремя символами, т.е. не 1, а 001, например.

23 (изменено: serzh82saratov, 2013-09-18 12:56:52)

Re: AHK: Как в НЕтекстовом файле заменить строку?

YMP
Сделать нетрудно, но зачем?


Loop % Length 
     NumLen := StrLen(Num := NumGet(buf, A_Index - 1, "UChar"))
    , hex .= (NumLen = 1 ? 00 Num : NumLen = 2 ? 0 Num : Num) " " 
MsgBox % hex
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Как в НЕтекстовом файле заменить строку?

Код из 21 отлично работает, особенно с дополнением из 23. Спасибо, жаль только, что  понимаю его на треть. Может со временем разберусь.

25

Re: AHK: Как в НЕтекстовом файле заменить строку?

особенно с дополнением из 23


Кроме усложнения обработки, что это даёт?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

26

Re: AHK: Как в НЕтекстовом файле заменить строку?

Для меня даёт наглядность при настройке и тестировании. Мне легче воспринимать в тестовом выводе, когда все элементы имеют одинаковую длину.  Мелочь, а приятно.

27 (изменено: serzh82saratov, 2013-09-18 16:57:13)

Re: AHK: Как в НЕтекстовом файле заменить строку?

Ну да, можно сворганить свой НЕХ точнее DEC редактор байтов.
Вот только зачем усложнять почти бесконечный цикл, если NumPut нужно только значение числа?
А при конвертации строки в цифры (это как я понял тоже понадобится), снова переделывать в трёхзначные, для осуществления поиска по тексту:


File := FileOpen(FileName, "r")   
Encoding := File.Encoding
file.Close()
string = 1 0 
VarSetCapacity( var, StrLen(string)) 
StrPut(string, &var, Encoding)
Loop % StrLen(string)
    str .= NumGet(var, A_Index - 1, "UChar") " "
MsgBox % str

Хотя до конца, все тонкости решения я непонимаю.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

28

Re: AHK: Как в НЕтекстовом файле заменить строку?

Ну, я вычленяя нужный фрагмент тупо использовал знакомые
StringGetPos
StrLen
StringTrimRight и т.п,
где, кстати тоже несколько удобнее представление всегда в виде трёх знаков.

29

Re: AHK: Как в НЕтекстовом файле заменить строку?

Кстати, после FileOpen не забывайте делать file.Pos = 0, т.е. устанавливать указатель файла на начало. Поскольку, если начальные байты случайно совпадут с байтами BOM для utf-8 или utf-16, то чтение файла начнётся после них, а не с самого начала. В какой-то теме этот казус уже обсуждался.

30 (изменено: serzh82saratov, 2013-09-18 16:18:03)

Re: AHK: Как в НЕтекстовом файле заменить строку?

Next пишет:

Ну, я вычленяя нужный фрагмент тупо использовал знакомые
StringGetPos
StrLen
StringTrimRight и т.п,
где, кстати тоже несколько удобнее представление всегда в виде трёх знаков.

Ничего непонял, можно это всё на примере.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

31

Re: AHK: Как в НЕтекстовом файле заменить строку?

Да, собственно и не важно.  Постараюсь разобраться и в 27, как время появится. Спасибо1