powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Оптимизация побайтового чтения и сравнения двух бинарных файлов
25 сообщений из 112, страница 1 из 5
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572066
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу знатоков помочь с оптимизацией побайтового чтения и сравнения двух бинарных файлов!

Ниже приведен несколько урезанный код самой процедуры...
(прошу не пинать за возможно большой код... но иначе возможно было бы больше от Вас уточнений и ухода темы в сторону)

Данная тема перекликается с моей же темой " Вывод в Memo японских иероглифов (932-я кодовая таблица) ", но об этом позже.

Немного словесного описания:
Процедура оперирует двумя бинарными файлами одинаковой длины:
- OriginalFile - бинарный файл в котором встречаются английские и японские текстовые фразы (в 932 или 20932 -й кодировке) с лидирующими и замыкающими нулевыми байтами;
- PerevedenFile - бин.файл созданный на основе предыдущего Оригинала, но японские фразы заменены на их английские аналоги, т.е. Переведены с учетом длины японской фразы включая Пред.и После-нули. Данный файл может быть "переведен" предварительно вручную или др.программой, это не важно!

Задача процедуры - на основании информации из файлов OriginalFile и PerevedenFile сформировать текстовый файл PerevodFile со структурой, упрощенно похожей на XML, который можно будет открывать для просмотра в текстовом редакторе (в дальнейшем буду иметь ввиду " Notepad++ "), так и в "WinHex".

Пришло время привести тестовые примеры этих Трех файлов, а затем - структуру выходного файла PerevodFile !?

OriginalFile :


PerevedenFile :


PerevodFile :


Но лучше на него взглянуть из " Notepad++ " (включена индикация "Всех" символов):
Эхх - картинка длинная получилась!..((( Надеюсь на 14'-вом монике никто не читает?..)

Или можно скопировать его сюда:
Код: xml
1.
2.
*#0082B182F182C982BF82CD000000#00476F6F64206D6F726E696E6700#こんにちは#Good morning#...You comments...##
*#00834F836283688378834300#00476F6F6420626179000000#グッドベイ#Good bay#...You comments...##

Правда упр.символов " CR " " LF " тут видно не будет!
Иероглифы скорее всего - тоже не проявятся..((
Тогда попробую еще просто вставить (да простят меня Модераторы и Админы форума!):

*#0082B182F182C982BF82CD000000#00476F6F64206D6F726E696E6700#こんにちは#Good morning#...You comments...##
*#00834F836283688378834300#00476F6F6420626179000000#グッドベイ#Good bay#...You comments...##


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

Зачем я это все пишу и вставляю картинки?
Да просто опережаю время, предвидя возможные наводящие вопросы и уточнения - стараюсь выложить всю начальную информацию!

Ну а тем, кто дочитал до этого места - собственно попробую сформулировать свой вопрос согласно топика...


Как видите - для чтения отдельных байт из файлов я использовал TFileStream , просто на этапе правильного составления алгоритма, так было удобней и легче!
Но читать по одному байту - как то не очень шустро получается!
Подскажите пожалуйста, для реализации данного алгоритма - какие варианты можно еще попробовать???

А тут сам код процедуры:
Код: 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.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
//------------------------------------------------------------------------------------------
procedure TMainForm.MainProcess(Sender: TObject);
var
SizeOriginal, SizePereveden: Integer;
Address: Integer;
SizeFraza: Integer;
NumberString: Integer; // Номер строки Перевода
i: Integer;
FrazaOk: Boolean; // Флаг найденного различия в фразах
begin
     MainMemo.Lines.Clear;
     // Считываем имена файлов из Полей редактирования (возможно редактировались!)
     FullOriginalFileName := FileBinOriginalEdit.Text;
     FullPerevedenFileName := FileBinPerevedenEdit.Text;
     FullPerevodFileName := DirPerevodEdit.Text + PerevodFileNameEdit.Text;

     try
          FOriginal:=TFileStream.Create(FullOriginalFileName, fmOpenRead, fmshareCompat);
          SizeOriginal := FOriginal.Size;
          FPereveden:=TFileStream.Create(FullPerevedenFileName, fmOpenRead, fmshareCompat);
          SizePereveden := FPereveden.Size;

          if SizeOriginal <> SizePereveden then
               begin  MainMemo.Lines.Add('Длины BIN-файлов НЕ РАВНЫ! Продолжение Невозможно!');
                      Exit;
               end;
          AddressFiles := 0;
          NumberString := 0;

          while AddressFiles < SizeOriginal do
               begin
                    TwoBytesRead(MainForm);  // Читаем ISimvol и PSimvol

                    if (ISimvol=0) and (PSimvol=0) then
                         begin
                              Address := AddressFiles;
                              SizeFraza := 1;
                              Inc(AddressFiles);
                              if AddressFiles >= SizeOriginal then Exit;

                              TwoBytesRead(MainForm);  // Читаем ISimvol и PSimvol

                              if (ISimvol<>0) and (PSimvol<>0) then
                                   begin
                                        FrazaOk:=False; // Сбрасываем флаг перед анализом.
                                        repeat
                                             if ISimvol<>PSimvol then FrazaOk:=True; // Нашли Разные байты в фразах

                                             Inc(SizeFraza);
                                             Inc(AddressFiles);

                                             if AddressFiles >= SizeOriginal then Exit;

                                             TwoBytesRead(MainForm);  // Читаем ISimvol и PSimvol
                                        until (ISimvol=0) and (PSimvol=0);

                                        if FrazaOk=True then
                                             begin
                                                  Inc(SizeFraza);
                                                  Inc(NumberString);

                                                  // Первые два Символа строки: "*#"
                                                  MainMemo.Lines.Add('*#');

                                                  // Пишем Исходные (JP_HEX)-----------------------------
                                                  for i:=0  to SizeFraza-1 do
                                                       begin
                                                            FOriginal.Seek((Address + i), soFromBeginning);
                                                            FOriginal.ReadBuffer(ISimvol,1);

                                                            MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] +
                                                            IntToHex(ISimvol, 2);
                                                       end;
                                                  MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] + '#';

                                                  // Пишем переведенные (ENG_HEX)------------------------
                                                  for i:=0  to SizeFraza-1 do
                                                       begin
                                                            FPereveden.Seek((Address + i), soFromBeginning);
                                                            FPereveden.ReadBuffer(PSimvol,1);

                                                            MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] +
                                                            IntToHex(PSimvol, 2);
                                                       end;
                                                  MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] + '#';

                                                  // Пишем исходные байты (JP_TXT)-----------------------
                                                  for i := 1 to SizeFraza-2 do
                                                       begin
                                                            FOriginal.Seek((Address + i), soFromBeginning);
                                                            FOriginal.ReadBuffer(ISimvol,1);

                                                            // Если это LF, то меняем его на "@"
                                                            if ISimvol=10 then ISimvol := 64; // 40 hex

                                                            MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] +
                                                            AnsiChar(ISimvol);
                                                       end;
                                                  MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] + '#';

                                                  // Пишем переведенные байты (ENG_TXT)------------------
                                                  for i := 1 to SizeFraza-2 do
                                                       begin
                                                            FPereveden.Seek((Address + i), soFromBeginning);
                                                            FPereveden.ReadBuffer(ISimvol,1);

                                                            // Если это LF, то меняем его на "@"
                                                            if ISimvol=10 then ISimvol := 64; // 40 hex

                                                            MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] +
                                                            AnsiChar(ISimvol);
                                                       end;
                                                  MainMemo.Lines[MainMemo.Lines.Count-1]:=MainMemo.Lines[MainMemo.Lines.Count-1] +
                                                   '#' + '...You comments...' + '##';
                                             end;
                                   end;
                         end
                     else
                         begin
                              Inc(AddressFiles);
                         end;
               end;
     finally
          FOriginal.Free;
          FPereveden.Free;

          MainMemo.Lines.SaveToFile(FullPerevodFileName); // Сохраняем Мемо в файл
          MainMemo.Lines.Add('Файл-Переводов "'+ FullPerevodFileName + ' записан!');

          if DublicateDel=True then // Если флаг УдаленияДублей=1, удаляем дубли
               begin  MainMemo.Lines.Add('Удаляем дубликаты строк в Файле-Переводов... "');
                         DublicateDelete(MainForm); // Процедура удаления дубликатов строк
               end;
          MainMemo.Lines.Add('Обработка файлов завершена!');
          if NumberString=0 then MainMemo.Lines.Add('Различий в Двоичных файлах не найдено!')
          else MainMemo.Lines.Add('Найдено Фраз-Перевода: ' + IntToStr(NumberString));
     end;
end;
//----------------------------------------------------------------------------------------------------


Для побайтного-посимвольного накопления выходного файла я использовал TMemo с последующей процедурой удаления дублей строк (ее текст тут упущен..) и выгрузкой его в файл.
Хотя наверное для этого можно использовать и TStringList !? - Надо попробовать его.

Формат получаемого файла " Perevod " полностью меня устраивает, единственное, что никак не могу понять:

MainMemo :


При выводе в TMemo всего этого "bla-bla-bla...", вместо японских иероглифов присутствую совсем другие символы!
(А в свойствах TMemo.Font зачем тогда присутствует выбор кодировки, в том числе 932 !? )

НО!!! - Вопрос по TMemo.Font - это совсем другая история и я уже начал по ней дискуссию ТАМ .

P.S. В данном топике меня интересует прежде всего - варианты оптимизации чтения!
(Ну а дальше - что позволят уважаемые Модераторы...)
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572100
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BellicПодскажите пожалуйста, для реализации данного алгоритма - какие варианты можно еще попробовать???
Можно начать отсюда https://www.google.com/search?q=delphi buffered file stream
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572120
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic(Ну а дальше - что позволят уважаемые Модераторы...)
Модератор настоятельно советует не злоупотреблять оформлением.
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572240
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

Я нифига не понял, чего тебе нужно. Изложи вопрос компактнее, пожалуйста

От себя замечу, что UniConv поддерживает 932 и 20932 кодировки. А значит и CachedTexts поддерживает их.
Значит ты можешь делать построчные Readln и вообще как угодно работать с текстом. Хоть через автокоррекцию в UTF8, хоть в Unicode, хоть в 51949
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572293
utf8 ? ... ...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
var
 LPos : Int64;
 ISymbol, PSymbol : Byte;
begin
 OpenFiles();
 if FOriginal.Size = FPereveden.Size then
    for LPos := 0 to FOriginal.Size div SizeOf(ISymbol) - 1 do begin
        FOriginal.Read(ISymbol, SizeOf(ISymbol));
        FPereveden.Read(PSymbol, SizeOf(PSymbol));
        if ISymbol<>PSymbol then Break;
    end;
 CloseFiles();
end;
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572307
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUUniConv поддерживает 932 и 20932 кодировки. А значит и CachedTexts поддерживает их.
дальше все про блох....
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572513
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadmanМожно начать отсюда https://www.google.com/search?q=delphi buffered file stream
wadman , Вам - большое спасибо за подсказку, а разработчикам за такой подарок - давно бы стоило это сделать!..)

Замена TFileStream на TBufferedFileStream на тестовом примере от сюда ( Faster FileStream with TBufferedFileStream ) выдала офигительный результат - вместо 2491 msec, тест сработал за 31 msec (это более чем в 80 раз быстрее!)
Только автор что-то там не так немного с подсчетом символа "#13" накрутил..) - я не стал разбираться.
Тестовый код из статьи
Код: 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.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
unit MainModule;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Diagnostics, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    btnWrite: TButton;
    btnRead: TButton;
    btnReadBuffered: TButton;
    procedure btnWriteClick(Sender: TObject);
    procedure btnReadClick(Sender: TObject);
    procedure btnReadBufferedClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//==============================================================================
procedure TForm1.btnWriteClick(Sender: TObject);
var
  sw: TStreamWriter;
  I: Integer;
begin
  sw := TStreamWriter.Create('test.txt', False, TEncoding.UTF8);
  try
    // write 10K lines
    sw.WriteLine ('Hello, world');
    for I := 1 to 99999 do
      sw.WriteLine ('Hello ' + I.ToString);
 finally
   sw.Free;
 end;
 Memo1.Lines.Add ('File written');

end;
//==============================================================================
procedure TForm1.btnReadClick(Sender: TObject);
var
 fStr: TFileStream;
 Total, I: Integer;
 sw: TStopwatch;
 ch: Char;
begin
  sw := TStopwatch.StartNew;
  fStr := TFileStream.Create('test.txt', fmOpenRead);
  try
    Total := 0;
    while fStr.Read (ch, 1) = 1 do begin
      if ch = #13 then
        Inc(Total);
    end;
    Memo1.Lines.Add ('Lines: ' + Total.ToString);
  finally
    fStr.Free;
  end;
  sw.Stop;
  Memo1.Lines.Add ('msec: ' + sw.ElapsedMilliseconds.ToString);

end;
//==============================================================================
procedure TForm1.btnReadBufferedClick(Sender: TObject);
var
  fStr: TBufferedFileStream;
  Total, I: Integer;
  sw: TStopwatch;
  ch: Char;
begin
  sw := TStopwatch.StartNew;
  fStr := TBufferedFileStream.Create('test.txt', fmOpenRead);
  try
    Total := 0;
    while fStr.Read (ch, 1) = 1 do
     begin
      if ch = #13 then
        Inc(Total);
     end;
    Memo1.Lines.Add ('Lines: ' + Total.ToString);
  finally
    fStr.Free;
  end;
  sw.Stop;
  Memo1.Lines.Add ('msec: ' +   sw.ElapsedMilliseconds.ToString);

end;
//==============================================================================
end.

Правда чтоб это работало - необходима свежая редакция Delphi - у меня стоит XE3 и 10.2.
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572565
|:|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
|:|
Гость
BellicДля побайтного-посимвольного накопления выходного файла я использовал TMemo Bellic... выдала офигительный результат - вместо 2491 msec, тест сработал за 31 msec (это более чем в 80 раз быстрее!)
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572596
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Глянул на исходники...

Я уже писал вам в другой теме, что код вида
Код: pascal
1.
2.
3.
4.
5.
6.
for i := 0 to SizeFraza - 1 do
begin
  FOriginal.Seek((Address + i), soFromBeginning);
  FOriginal.ReadBuffer(ISimvol, 1);
  MainMemo.Lines[MainMemo.Lines.Count-1] := MainMemo.Lines[MainMemo.Lines.Count-1] + IntToHex(ISimvol, 2);
end;

и слово "скорость", взаимосвязаны примерно как гиппопотам и стратосферные полёты.

Ради интереса, запустите своё приложение в режиме отладчика (с включенной опцией Use Debug DCUs ) и пройдитесь кнопкой F7 (Trace Into) по этому циклу, посмотрите сколько и какого кода там выполняется.
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572627
SoftForYou
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BellicwadmanМожно начать отсюда https://www.google.com/search?q=delphi buffered file stream
wadman , Вам - большое спасибо за подсказку, а разработчикам за такой подарок - давно бы стоило это сделать!..)

Замена TFileStream на TBufferedFileStream на тестовом примере от сюда ( Faster FileStream with TBufferedFileStream ) выдала офигительный результат - вместо 2491 msec, тест сработал за 31 msec (это более чем в 80 раз быстрее!)
Только автор что-то там не так немного с подсчетом символа "#13" накрутил..) - я не стал разбираться.
Тестовый код из статьи
Код: 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.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
unit MainModule;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Diagnostics, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    btnWrite: TButton;
    btnRead: TButton;
    btnReadBuffered: TButton;
    procedure btnWriteClick(Sender: TObject);
    procedure btnReadClick(Sender: TObject);
    procedure btnReadBufferedClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//==============================================================================
procedure TForm1.btnWriteClick(Sender: TObject);
var
  sw: TStreamWriter;
  I: Integer;
begin
  sw := TStreamWriter.Create('test.txt', False, TEncoding.UTF8);
  try
    // write 10K lines
    sw.WriteLine ('Hello, world');
    for I := 1 to 99999 do
      sw.WriteLine ('Hello ' + I.ToString);
 finally
   sw.Free;
 end;
 Memo1.Lines.Add ('File written');

end;
//==============================================================================
procedure TForm1.btnReadClick(Sender: TObject);
var
 fStr: TFileStream;
 Total, I: Integer;
 sw: TStopwatch;
 ch: Char;
begin
  sw := TStopwatch.StartNew;
  fStr := TFileStream.Create('test.txt', fmOpenRead);
  try
    Total := 0;
    while fStr.Read (ch, 1) = 1 do begin
      if ch = #13 then
        Inc(Total);
    end;
    Memo1.Lines.Add ('Lines: ' + Total.ToString);
  finally
    fStr.Free;
  end;
  sw.Stop;
  Memo1.Lines.Add ('msec: ' + sw.ElapsedMilliseconds.ToString);

end;
//==============================================================================
procedure TForm1.btnReadBufferedClick(Sender: TObject);
var
  fStr: TBufferedFileStream;
  Total, I: Integer;
  sw: TStopwatch;
  ch: Char;
begin
  sw := TStopwatch.StartNew;
  fStr := TBufferedFileStream.Create('test.txt', fmOpenRead);
  try
    Total := 0;
    while fStr.Read (ch, 1) = 1 do
     begin
      if ch = #13 then
        Inc(Total);
     end;
    Memo1.Lines.Add ('Lines: ' + Total.ToString);
  finally
    fStr.Free;
  end;
  sw.Stop;
  Memo1.Lines.Add ('msec: ' +   sw.ElapsedMilliseconds.ToString);

end;
//==============================================================================
end.

Правда чтоб это работало - необходима свежая редакция Delphi - у меня стоит XE3 и 10.2.

Чё-то не понял, у тебя же файл японский, а не юникодовый. Почему ты читаешь Char?
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572631
SoftForYou
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И какой вообще смысл читать посимвольно файл?
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572658
SoftForYou
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
type
  TJapaneesTextReader = class(TUTF16TextReader)
  public
    constructor Create(const Source: TCachedReader; const Owner: Boolean);
    constructor CreateFromFile(const FileName: string);
  end;

constructor TJapaneesTextReader.Create(const Source: TCachedReader; const Owner: Boolean);
var
  Context: PUniConvContext;
begin
  Context := Self.GetInternalContext;
  Context.Init(CODEPAGE_UTF16, 20932, ccOriginal);
  CreateDirect(Context, Source, Owner);
end;

constructor TJapaneesTextReader.CreateFromFile(const FileName: string);
begin
  FFileName := FileName;
  Create(TCachedFileReader.Create(FileName), True);
end;



А потом читаешь построчно:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var
  S: UTF16String{быстрее} или UnicodeString; 
  Reader: TJapaneesTextReader;
begin
  Reader := TJapaneesTextReader.CreateFromFile(имя файла);
  try
    while Reader.Readln(S) do
    begin
      // ToDo
    end;
  finally
    Reader.Free;
  end;
end;



А посимвольно можно так. Для Char (WideChar) можно сделать быстрее, только расписывать не буду :)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
var
  C: UCS4Char;
  Reader: TJapaneesTextReader;
begin
  Reader := TJapaneesTextReader.CreateFromFile(имя файла);
  try
    while not Reader.EOF do
    begin
      C := Reader.ReadChar;
      // ToDo
    end;
  finally
    Reader.Free;
  end;
end;
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572664
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvpГлянул на исходники...

Я уже писал вам в другой теме, что код вида
Код: pascal
1.
2.
3.
4.
5.
6.
for i := 0 to SizeFraza - 1 do
begin
  FOriginal.Seek((Address + i), soFromBeginning);
  FOriginal.ReadBuffer(ISimvol, 1);
  MainMemo.Lines[MainMemo.Lines.Count-1] := MainMemo.Lines[MainMemo.Lines.Count-1] + IntToHex(ISimvol, 2);
end;

и слово "скорость", взаимосвязаны примерно как гиппопотам и стратосферные полёты.

Ради интереса, запустите своё приложение в режиме отладчика (с включенной опцией Use Debug DCUs ) и пройдитесь кнопкой F7 (Trace Into) по этому циклу, посмотрите сколько и какого кода там выполняется.
Рано я обрадовался!!!
Замена TFileStream на TBufferedFileStream в реальной процедуре скорости ей не прибавила, и даже наоборот (было 193 сек, а стало - 196 сек)!

И с Вам, alekcvp , я тоже полностью согласен, что вышеуказанный цикл "гиппопотамовский"!

Индикация в Memo в принципе вообще не нужна, а произвести формирование Выходного файла думаю можно и в TStringList , а потом командой SaveToFile сохранить его в файле!?
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572669
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SoftForYouЧё-то не понял, у тебя же файл японский, а не юникодовый. Почему ты читаешь Char?
Вообще то читаю и анализирую побайтно (ISimvol, PSimvol: Byte;) потому, что в Исходных файлах могут быть не только 2-х байтные, но и 1-байтные японские символы (932 и 20932-й кодировок), латиница, а так же просто например машинный код для процессора!

SoftForYou , я ответил на Ваш вопрос?
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572675
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SoftForYouИ какой вообще смысл читать посимвольно файл?
Исходные файлы OriginalFile и PerevedenFile - это Бинарники, а не Текстовые!
Это вообще-то "прошивки" для электронных устройств (машинный код!) с некоторым числом Текстовых фраз!
По другому тут я думаю никак не получится!
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572759
Bellicэто Бинарники, а не Текстовые!Bellic, методичку по массивам почитай ))
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572776
SoftForYou
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bellic,

Тогда тебе нужен CachedBuffers
По сути тебе нужен только CachedBuffers.pas

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var
  B: Byte;
  Reader: TCachedFileReader;
begin
  Reader := TCachedFileReader.Create(имя файла);
  try
    while (not Reader.EOF) do
    begin
      Reader.ReadData(B);
      // ToDo
    end;
  finally
    Reader.Free;
  end;



Это самый быстрый способ побайтного чтения твоих файлов
Но я думаю, скорость у тебя проседает не на чтении файлов, а в каких-то других местах, например, при переводе строки в юникод
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39572915
ОнСамый
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попкорновый файлBellicэто Бинарники, а не Текстовые!Bellic, методичку по массивам почитай ))
На предмет чего?
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573188
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Думал насчет использования массивов, но пока решил повременить...

В общем отказался от TMemo для "формирования и накопления" строк и последующего сохранения его в файл...
(Вывод в TMemo оставил только для информационных сообщений)
Чтение бинарников оставил через TFileStream .

Сейчас это выглядит примерно так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
MString: TStrings;
SStroka: AnsiString;
...
MString := TStringList.Create;
...
SStroka := '*#';
...
for i := 0 to SizeFraza - 1 do
begin
  FOriginal.Seek((Address + i), soFromBeginning);
  FOriginal.ReadBuffer(ISimvol, 1);
  //MainMemo.Lines[MainMemo.Lines.Count-1] := 
  //      MainMemo.Lines[MainMemo.Lines.Count-1] + IntToHex(ISimvol, 2);
  SStroka := SStroka + IntToHex(ISimvol, 2);
end;
...
MString.Add(SStroka);
...
MString.SaveToFile(FileName);


В результате - время выполнения процедуры от 193 секунд уменьшилось до 87 !
(Забыл ранее упомянуть, что размер бинарников - каждый примерно по 10 Мбайт )

В принципе - результатом более или менее доволен, но думаю что можно еще подчистит код или попробовать другие варианты реализации, в том числе и с Массивами!
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573273
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic(Забыл ранее упомянуть, что размер бинарников - каждый примерно по 10 Мбайт )
Копейки... Можно разом загрузить и не дергать чтение по байтам.
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573343
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BellicСейчас это выглядит примерно так:
Код: pascal
1.
2.
3.
4.
for i := 0 to SizeFraza - 1 do
begin
  FOriginal.Seek((Address + i), soFromBeginning);
  FOriginal.ReadBuffer(ISimvol, 1);



1. При последовательном чтении Seek() делать не надо, Read[Buffer]() сама переносит указатель на Count позиций вперёд.
2. Для разнообразия:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  const
    HexChars: array [0..15] of AnsiChar = '0123456789ABCDEF';
  var
    Buffer: TBytes;
    SStroka: AnsiString;
  ...
  SetLength(SStroka, (SizeFraza + 1) * 2);
  SStroka[1] := '*';
  SStroka[2] := '#';  
  ... 
  SetLength(Buffer, SizeFraza);
  FOriginal.Seek(Address, soFromBeginning);
  FOriginal.ReadBuffer(Buffer[0], SizeFraza); // чтение не побайтное, а одним куском
  for i := 0 to SizeFraza - 1 do begin
    SStroka[i * 2 + 3] := HexChars[Buffer[i] shr 4];
    SStroka[i * 2 + 4] := HexChars[Buffer[i] and $0F];
  end;
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573396
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

Загрузи исходные файлы в память, так будет быстрее и удобнее
А запись в файл у тебя очень долгая - ты постоянно перевыделяешь строки и используешь конкатенацию. Тебе нужно использовать TCachedTextWriter и TTemporaryString. В общем не очень ясно, зачем ты у нас что-то спрашиваешь, если вообще не прислушиваешься к тому, что мы говорим :)
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573535
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SoftForYouBellic,
Тогда тебе нужен CachedBuffers
По сути тебе нужен только CachedBuffers.pas
я так понимаю - это компонент? Возможно попробую чуть позже... правда это утяжелит программу...

wadman..Можно разом загрузить и не дергать чтение по байтам.
Думаю Вы правы! Но в 2-х циклах из 4-рех идет не только побайтное чтение, но и анализ этих данных, да и обвязка для "загрузки разом" будет стоить некоторого кода..(

alekcvp1. При последовательном чтении Seek() делать не надо, ReadBuffer]() сама переносит указатель на Count позиций вперёдЭто известно мне, Seek() остался от вырисовывания алгоритма, сейчас приведу в порядок где это возможно. Спасибо за подсказку!

alekcvp
2. Для разнообразия:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  const
    HexChars: array [0..15] of AnsiChar = '0123456789ABCDEF';
  var
    Buffer: TBytes;
    SStroka: AnsiString;
  ...
  SetLength(SStroka, (SizeFraza + 1) * 2);
  SStroka[1] := '*';
  SStroka[2] := '#';  
  ... 
  SetLength(Buffer, SizeFraza);
  FOriginal.Seek(Address, soFromBeginning);
  FOriginal.ReadBuffer(Buffer[0], SizeFraza); // чтение не побайтное, а одним куском
  for i := 0 to SizeFraza - 1 do begin
    SStroka[i * 2 + 3] := HexChars[Buffer[i] shr 4];
    SStroka[i * 2 + 4] := HexChars[Buffer[i] and $0F];
  end

;
Это еще не совсем понял, разберусь думаю..

SOFT FOR YOUЗагрузи исходные файлы в память, так будет быстрее и удобнееОтличная идея!!! Следующий вариант попробую именно его!
А запись в файл у тебя очень долгая - ты постоянно перевыделяешь строки и используешь конкатенацию.Конкатенацию юзать удобно - не надо следить за указателем позиции.
А запись в файл в свете варианта использования " TStringList ", выглядит одной строкой:
Код: pascal
1.
MString.SaveToFile(FileName);


Тебе нужно использовать TCachedTextWriter и TTemporaryString. В общем не очень ясно, зачем ты у нас что-то спрашиваешь, если вообще не прислушиваешься к тому, что мы говорим :)
SOFT FOR YOU , я думаю Вы зря обвиняете меня в невнимательности к предложениям пользователей!
Замену TFileStream на TBufferedFileStream попробовал;

От TMemo с позицированием в нем (типа " Memo.Lines[Memo.Lines.Count-1]:=Memo.Lines[Memo.Lines.Count-1] + '#'; ") тоже избавился.

Массив частично заюзал - " SStroka: AnsiString; " - это же по сути тот же массив, но символьный!?

...при возможности - обязательно попробую предложенные Вами варианты...

P . S . К сожалению (или к счастью?!) мы все люди (как ни странно...), а не машины!
У каждого свои достоинства, недостатки и Время - для их приумножения или искоренения!...
Спасибо Всем, за то что Вы сейчас со мной, здесь и сейчас!!!
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573834
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

>Конкатенацию юзать удобно - не надо следить за указателем позиции.

Удобно, но медленно. Указатель - всего лишь одна переменная + 1-2 строки кода. Многократное ускорение стоят того, что бы разобраться.
...
Рейтинг: 0 / 0
Оптимизация побайтового чтения и сравнения двух бинарных файлов
    #39573898
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonBellic,

>Конкатенацию юзать удобно - не надо следить за указателем позиции.

Удобно, но медленно. Указатель - всего лишь одна переменная + 1-2 строки кода. Многократное ускорение стоят того, что бы разобраться.
Ну я не стою на месте...
Правда неудачно "выкосил" Seek , в результате чего сломался алгоритм и в выходном файле появились ошибочные данные...((
Будет время - пройдусь пошагово на тестовых файлах...
А уже после этого - буду думать что еще можно оптимизировать! Хотелось бы дорешать этот вариант!
...
Рейтинг: 0 / 0
25 сообщений из 112, страница 1 из 5
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Оптимизация побайтового чтения и сравнения двух бинарных файлов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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