Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Поиск и Замена последовательности байт в бинарном файле / 11 сообщений из 11, страница 1 из 1
06.11.2017, 16:34:55
    #39548428
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
Прошу знатоков сильно не пинать новичка, а помочь отладить следующий код:

Имеем файл " file.bin " длиной 64 байта следующего тестового содержания(первая строчка-адрес):
000102030405060708090A0B0C0D0E0FFFFFFF003132333400FFFF0031323300FFFFFFFFFFFFFF003132333400FFFFFF

Программа ищет определенные последовательности байт (массив " Poisk ") и заменяет их на другие (массив " Zamena ")

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
unit Main_Module;

interface

uses
  Winapi.Windows,  System.SysUtils, System.Classes,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TMainForm = class(TForm)
    OpenDialog: TOpenDialog;
    btnStart: TButton;
    btnOpenFile: TButton;
    edtOpenFile: TEdit;
    Memo: TMemo;
    procedure btnOpenFileClick(Sender: TObject);
    procedure btnStartClick(Sender: TObject);

  private
    { Private declarations }
    FullFileName: String;     // Полное имя файла
    FBin: TFileStream;
  public
    { Public declarations }
  end;
var
     MainForm: TMainForm;

implementation

{$R *.dfm}

//==================== Процедура открытия БИН-файла ============================
procedure TMainForm.btnOpenFileClick(Sender: TObject);
begin
     if OpenDialog.Execute then FullFileName := OpenDialog.FileName;
          try
               FBin:=TFileStream.Create(FullFileName, fmOpenRead);
               edtOpenFile.Text := FullFileName;
          finally
               FBin.Free;
          end;
end;
//================= Конец процедуры открытия БИН-файла =========================

//======================== Процедура Поиска и Замены ===========================
procedure TMainForm.btnStartClick(Sender: TObject);
var
MBin: TMemoryStream;     // файл in Memory
SizeFile: Dword;         // Длина файла
pCurrent: Pointer;
P: PChar;
const
Poisk: array[0..5] of Byte = ($00, $31, $32, $33, $34, $00);    // массив Поиска
Zamena: array[0..5] of Byte = ($00, $35, $36, $37, $38, $00);   // массив Замены
begin
     try
          FullFileName := edtOpenFile.Text; // Считываем имя файла
          MBin:=TMemoryStream.Create;
          MBin.LoadFromFile(FullFileName);
          SizeFile := MBin.Size;
//-------------------- Код поиска и замены ------------------------------
     pCurrent := MBin.Memory; //  адрес в памяти
     P := PChar(pCurrent);
     //while  Integer(pCurrent) + SizeOf(Poisk) < SizeBinFile do
     while  P <= (PChar(pCurrent) + SizeFile - length(Poisk)) do
          begin
               if CompareMem(P, @Poisk[0], length(Poisk)) then
                    begin //---- Найдено совпадение ----
                         CopyMemory(P, @Zamena[0], length(Poisk)); // Копируем Замену вместо Поиска
                         P := P + length(Poisk); // Коррекция на длину Поиска, чтоб искать дальше
                    end
               else
                    begin //---- Нет совпадения ---------
                         inc(P); // продолжаем дальше искать по файлу
                    end;
          end;
//-----------------------------------------------------------------------
     finally
          MBin.SaveToFile(FullFileName); // Пишем МЕмори в файл
          FreeAndNil(MBin);
     end;
end;
//===================== Конец процедуры Поиска и Замены ========================
end.



Код был позаимствован вот от сюда: https://groups.google.com/forum/#!topic/fido7.ru.delphi.chainik/_U4HgdMDwpo ,
Но вместо FileMapping -га была сделана попытка применить TMemoryStream

Что-то видимо нужно немного подправить в выделенном куске кода ,
у самого ума видимо еще не хватает и знаний!...
...
Рейтинг: 0 / 0
06.11.2017, 16:42:46
    #39548437
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
Bellic
Код: pascal
1.
P: PChar;

Заменить на PByte или PAnsiChar. Это однозначно. Если не поможет, тогда выкладывайте сюда что было в файле и что стало
...
Рейтинг: 0 / 0
06.11.2017, 16:48:18
    #39548441
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
_Vasilisk_Bellic
Код: pascal
1.
P: PChar;

Заменить на PByte или PAnsiChar. Это однозначно. Если не поможет, тогда выкладывайте сюда что было в файле и что стало

Изначально (С тем кодом, что приведен выше) файл вообще не менялся...

Сейчас попробую заменить P: PChar на P: PByte или P: PAnsiChar ...
...
Рейтинг: 0 / 0
06.11.2017, 17:05:35
    #39548462
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
Заменил:
Код: pascal
1.
2.
3.
4.
5.
//P: PChar;
P: PByte;
...
//P := PChar(pCurrent);
P := PByte(pCurrent);


И все сработало, как было задумано!!! (Результат на фото прилагается...)
Осталось проверить - как будет работать, если Искомая последовательность будет в конце файла:

.... FF FF 00 31 32 33 34 00
... проверил и в конце файла... Замечательно!
Спасибо Огромнейшее, _Vasilisk_ !!!
...
Рейтинг: 0 / 0
06.11.2017, 17:46:28
    #39548487
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
BellicЗаменил:
Код: pascal
1.
2.
3.
4.
5.
//P: PChar;
P: PByte;
...
//P := PChar(pCurrent);
P := PByte(pCurrent);

У Вас юникодная делфи. Соответственно
Код: pascal
1.
SizeOf(Char) = 2

. А значит
Код: pascal
1.
P := P + k;

смещало указатель не на k байт, а на 2*k
...
Рейтинг: 0 / 0
06.11.2017, 18:58:52
    #39548524
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
В следующей строке:
Код: pascal
1.
while  P <= (PChar(pCurrent) + SizeFile - length(Poisk)) do


видимо тоже нужно было поменять
Код: pascal
1.
PChar(pCurrent)

на
Код: pascal
1.
PByte(pCurrent)



Хотя оно и так все работало, но поменял...)

ЗЫ: При переносе изменений в ОСНОВНОЙ проект - почему-то опять поиск-замена перестали работать..(((
НО это уже другая история - буду отлаживать все пошагово, с проверками переменных
...
Рейтинг: 0 / 0
16.11.2017, 10:35:06
    #39554118
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
_Vasilisk_ , привет!
Хотел в Личке пообщаться, но похоже ее тут не предусмотрено?..(((
...
Маленький вопросик (правда ОффТопик..)
Отлаживаю и прилизываю свою программу... В ней есть временное Disabled элементов на форме на время выполнения отдельных задач с последующим Enabled.
В общем - эти Enabled-Disabled иногда неправильно срабатывают как надо...
Нет ли у тебя готового кода, чтоб его можно было вставить в событие OnMouseMove нужных элементов, чтоб при пролете мышкой над ними как-то индицировалось состояние данного элемента?
...
Рейтинг: 0 / 0
16.11.2017, 10:51:45
    #39554128
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
Bellic
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
//==================== Процедура открытия БИН-файла ============================
procedure TMainForm.btnOpenFileClick(Sender: TObject);
begin
     if OpenDialog.Execute then FullFileName := OpenDialog.FileName;
          try
               FBin:=TFileStream.Create(FullFileName, fmOpenRead);
               edtOpenFile.Text := FullFileName;
          finally
               FBin.Free;
          end;
end;
//================= Конец процедуры открытия БИН-файла =========================



Вот это - зачем ?
...
Рейтинг: 0 / 0
16.11.2017, 11:01:39
    #39554143
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
schiВот это - зачем ?
Не обращаем на мелочи внимание!
Приведенный в начале текст программы - это всего лишь минимизированный " кусочек " из огромного проекта, сосредоточенный лишь на теме Топика!!!

А в данной процедуре:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
//==================== Процедура открытия БИН-файла ============================
procedure TMainForm.btnOpenFileClick(Sender: TObject);
begin
     if OpenDialog.Execute then FullFileName := OpenDialog.FileName;
          try
               FBin:=TFileStream.Create(FullFileName, fmOpenRead);
               edtOpenFile.Text := FullFileName;
          finally
               FBin.Free;
          end;
end;
//================= Конец процедуры открытия БИН-файла =========================


Были вырезаны дополнительные проверки на корректность Пути и Имени файла и прочие мелочи!
...
Т.е. в конкретном случае в процедуре просто получаем FullFileName

schi , я ответил на Ваш вопрос?
...
Рейтинг: 0 / 0
16.11.2017, 11:07:22
    #39554151
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
Кстати - алгоритм отлично работает на больших двоичных файлах!
Огромный респект _Vasilisk_ !!! (И привет Харькову! - я 4 года там жил и учился...)
В результате время обработки одного и того же БИН-файла размером примерно 9 Мбайт сократилось с 24-х часов до 2-х минут!...)))
Естественно - ищется и заменяется не одна "последовательность байт"!
...
Рейтинг: 0 / 0
16.11.2017, 11:39:12
    #39554180
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск и Замена последовательности байт в бинарном файле
BellicМаленький вопросик (правда ОффТопик..)

Создайте отдельный вопрос, чтобы не путать мухи и котлеты.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Поиск и Замена последовательности байт в бинарном файле / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]