powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Поиск и Замена последовательности байт в бинарном файле
11 сообщений из 11, страница 1 из 1
Поиск и Замена последовательности байт в бинарном файле
    #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
Поиск и Замена последовательности байт в бинарном файле
    #39548437
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic
Код: pascal
1.
P: PChar;

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

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

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

Сейчас попробую заменить P: PChar на P: PByte или P: PAnsiChar ...
...
Рейтинг: 0 / 0
Поиск и Замена последовательности байт в бинарном файле
    #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
Поиск и Замена последовательности байт в бинарном файле
    #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
Поиск и Замена последовательности байт в бинарном файле
    #39548524
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В следующей строке:
Код: pascal
1.
while  P <= (PChar(pCurrent) + SizeFile - length(Poisk)) do


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

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



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

ЗЫ: При переносе изменений в ОСНОВНОЙ проект - почему-то опять поиск-замена перестали работать..(((
НО это уже другая история - буду отлаживать все пошагово, с проверками переменных
...
Рейтинг: 0 / 0
Поиск и Замена последовательности байт в бинарном файле
    #39554118
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_ , привет!
Хотел в Личке пообщаться, но похоже ее тут не предусмотрено?..(((
...
Маленький вопросик (правда ОффТопик..)
Отлаживаю и прилизываю свою программу... В ней есть временное Disabled элементов на форме на время выполнения отдельных задач с последующим Enabled.
В общем - эти Enabled-Disabled иногда неправильно срабатывают как надо...
Нет ли у тебя готового кода, чтоб его можно было вставить в событие OnMouseMove нужных элементов, чтоб при пролете мышкой над ними как-то индицировалось состояние данного элемента?
...
Рейтинг: 0 / 0
Поиск и Замена последовательности байт в бинарном файле
    #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
Поиск и Замена последовательности байт в бинарном файле
    #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
Поиск и Замена последовательности байт в бинарном файле
    #39554151
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати - алгоритм отлично работает на больших двоичных файлах!
Огромный респект _Vasilisk_ !!! (И привет Харькову! - я 4 года там жил и учился...)
В результате время обработки одного и того же БИН-файла размером примерно 9 Мбайт сократилось с 24-х часов до 2-х минут!...)))
Естественно - ищется и заменяется не одна "последовательность байт"!
...
Рейтинг: 0 / 0
Поиск и Замена последовательности байт в бинарном файле
    #39554180
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BellicМаленький вопросик (правда ОффТопик..)

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


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