![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Хочу написать конвертер бинарного файла, который переводит его на читабельный вид. Есть описание бинарного файла (структура) и сам файл. Не могу понять, как использовать описание этого файла при написании конвертера. С чего оттолкнуться, с чего начать подскажите пожалуйста
|
#2
|
||||
|
||||
![]() для начала можно сделать просмотр в HEX+ASCII-виде, как это делает, например, Total Commander: F3-Options-Hex. вполне читабельно
![]() Пишу программы за еду. __________________ |
#3
|
||||
|
||||
![]() Цитата:
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#4
|
||||
|
||||
![]() Есть готовый компон, который тебе представляет файл в стиле WinHEX.
MSHexEdit. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#5
|
|||
|
|||
![]() задача как-то неясно поставлена.
Начать можно например с чтения файла в структуру Например так Код:
type TMyStruct=record <здесь описание структуры> end; var z:TMyStruct; //сюда копируется файл procedure ReadMyStruct(fnam:string); var F:file of TMyStruct; begin assignfile(F,Fnam);reset(F); read(F,z); CloseFile(F); end; а еще рекомендую почитать описание функций BlockRead, BlockWrite, работа с типированными и нетипированными файлами. |
#6
|
||||
|
||||
![]() Цитата:
Берем книгу Льва Толстого и ставим в холодильник. Зачем читать файл в некую структуру? Файл произвольных двоичных данных. Вообще достаточно вычитывать по 16 байт за проход цикла, в array of byte к примеру, после чего в конечный файл записывать эти данные, обработав ф-ей IntToHex. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#7
|
||||
|
||||
![]() M.A.D.M.A.N.
Да с чего ты взял что нужно HEX-представление? Есть просто файл и есть описание, сколько байт прочитать для одной переменно сколько для другой и т.д. BlockRead и все. Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#8
|
|||
|
|||
![]() И так есть бинарный файл, я написал программку, которая считывает ее. А также есть описание структуры файла, не могу понять как использовать ее, в смысле как написать эту структуру программно. Я так понял описание структуры файла используется чтобы мы правильно прочитали этот файл. Вот вложил описание этого файла.
|
#9
|
||||
|
||||
![]() Итак пойдем плясать от печки:
1. У вас возможны 3 вида файла: IA.ICAMA, IA.ICIAR, IA.ICINA Последние 5 букв видимо расширение по которому вы будете определять тип данных в конкретном файле. Для первого типа файла имеем такое описание: Цитата:
Код:
Type ICAMA = record Data: Array[1..8192] of byte; end; И код для чтения данных записями будет такой: Код:
Type ICAMA = record Data: Array[1..8192] of byte; end; Var F: File of ICAMA; R: ICAMA; begin AssignFile(F, 'c:\IA.ICAMA'); Reset(F); while not Eof(F) do Read(F, R); CloseFile(F); end. ![]() А вот что касается чтения содержимого каждой из записи - это уже скорее всего в работу. Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. Последний раз редактировалось Страдалецъ, 22.08.2011 в 14:39. |
#10
|
|||
|
|||
![]() А почему нельзя загнать файл в поток и работать с потоками?
Остальное все описано в том документе. Сложного там я не вижу ничего. Смотри пунт 5. Говори что думаешь, думай, что говоришь. (Шоссе 60) Последний раз редактировалось OnzMill, 22.08.2011 в 19:01. |
#11
|
||||
|
||||
![]() Можно и в поток, но не думаю, что автору темы будет легче от этого.
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#12
|
|||
|
|||
![]() Вот дан ПРИМЕР. ПАКЕТ 101: НОМЕР АБОНЕНТА Б
ПРИМЕР: 078912345 (набираемые цифры) №--|Байтовая|Длина|------Hазвание поля-----------|Битовая позиция | поля|позиция |_____|_7|_6|_5_|_4_|_3_|_2_|_1_|_0|7_6_5_4_3_2_1_ 0_| _1__|__1_____|_1___|______НОМЕР ПАКЕТА________|_____6__|__5____ | _2__|__2_____|_12__|_РЕЗ|_ДЛИНА № АБОНЕТА Б___|_____0__|__9____ | _3__|__3_____|----------№ АБОНЕНТА Б-------------|------0--|--7-----| -----|__4_____|-------------------------------------|------8--|---9-----| -----|__5_____|-------------------------------------|------1--|---2-----| -----|__6_____|-------------------------------------|------3--|---4-----| -----|__7_____|_________________________________|_____5 __|_______| Уважаемые форумчане вот смотрю на этот пример и ничего не пойму. Подскажите пожалуйста непонятливому как описать этот пример программно. |
#13
|
|||
|
|||
![]() у меня получилось примерно это
Функции не тестировал, заранее приношу извинения за ошибки. короче, разбираться со всем этим надо долго и тоскливо. особенно угнетает переменная длина, из-за чего надо использовать динамич массивы. При чтении файла не забудь команду выделения под него памяти SetLength(NumAbon, <длина номера абонента>) Возможно лучшим решением было бы использовать потоки. Код:
type TP101=record Packet:byte; // номер пакета=101 Dlina:byte; // рез + длина номера NumAbon:array of byte; // номер абонента end; var P101:Tp101; function GetRes():integer; begin Result:=P101.Dlina shr 6; end; function GetDlinaNum():integer; begin Result:=P101.Dlina and $3F; end; {--------------------------------------------------------- переводит упакованный массив байт номера абонента в строку на Ассемблере было бы изящнее. Но учитывая малую длину поля-можно и так. ------------------------------------------------------------} function UnPack(var NN:array of byte):string; var p:^byte; begin Result:=''; p:=@NN[0]; //уст указатель на 1 байт -1 dec(p,1); repeat inc(p); Result:=Result + char(p^ shr 4 + ord('0')) + char((p^ and $FF + ord('0'))); until p=@NN[High(NN)]; end; |
#14
|
|||
|
|||
![]() Вот что получилось.
Код:
type AMA = packed record RecId : Byte; //Идентификатор записи LenRec : Word; //Длина записи Flags : array[1..3] of Byte; //Флажки SeqAndStat : Byte; //Посл-сть записи Статус оплаты LenLacAndOwnId : Byte; //Длина LAC и ID владельца {DnA : TStream; - Проблема в том что не умею работать с потоками: как использовать поток затем вывести данные} DnA : array[1..5] of Byte; //Переменная часть - Номер абонента А - значение массива просто подобрал //исп. hexviewer //Если просто пишу DnA : array of Byte; то выходит ошибка, где говорится о том //что требуется финализация переменной f: file of AMA; //Значение переменного массива рассчитывается как DnA : array[1..i] of Byte //где i = div [(LenLacAndOwnId+1)/2] //Описание Пакета № 100 Np100 : Byte; //Номер пакета Date : array[1..3] of Byte; //Дата Time : array[1..3] of Byte; //Время Flags100 : Byte; //Флажки Пакета № 100 Prod : array[1..3] of byte;//Прод-сть //Описание Пакета № 101 Np101 : Byte; //Номер пакета LenDnB : Byte; //Длина номера абонента Б {DnB : TStream; - Проблема в том что не умею работать с потоками: как использовать поток затем вывести данные} DnB : array[1..1] of Byte; //Переменная часть - Номер абонента Б - значение массива просто // подобрал исп. hexviewer //Если просто пишу DnA : array of Byte; то выходит ошибка, где говорится о том //что требуется финализация переменной f: file of AMA; //Значение переменного массива рассчитывается как DnB : array[1..j] of Byte //где j = div [(LenDnB+1)/2] //Описание Пакета № 130 Np130 : Byte; //Номер пакета LenP : Byte; //Длина пакета Zp : Word; //Значение причины RezAndOpr : byte; //Резерв и определение //Описание Пакета № 103 Np103 : Byte; //Номер пакета TeTv : array[1..3] of byte; // Тарифные единицы для тарификации вызова end; TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; OpenDialog: TOpenDialog; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var f: file of AMA; open : Topendialog; Rec : AMA; Buffer : array [0..8191] of byte; NumRecsRead,t : integer; begin memo1.Clear; open := TOpenDialog.Create(self); open.InitialDir := 'C:\000'; open.Options := [ofFileMustExist]; open.Filter := 'ama files|*.*'; open.Execute; AssignFile(f,open.FileName); {$I-} Reset(f); {$I+} seek(f,0); {while not eof(f) do begin} Read(f,Rec); memo1.Lines.Add(inttostr(Rec.RecId) + ' - ИДЕНТИФИКАТОР ЗАПИСИ'); memo1.Lines.Add(inttostr(Rec.LenRec) + ' - ДЛИНА ЗАПИСИ'); memo1.Lines.Add(inttostr(Rec.Flags[1]) + ' - Флажок F12'); memo1.Lines.Add(inttostr(Rec.Flags[2]) + ' - Флажок F12'); memo1.Lines.Add(inttostr(Rec.Flags[3]) + ' - Флажок F12'); memo1.Lines.Add(inttostr(Rec.SeqAndStat) + ' - Посл-сть записи и статус оплаты'); memo1.Lines.Add(inttostr(Rec.LenLacAndOwnId) + ' - Длина LAC и ID владельца'); memo1.Lines.Add(inttohex(Rec.DnA[1],1) + inttohex(Rec.DnA[2],1) + inttohex(Rec.DnA[3],1) + inttohex(Rec.DnA[4],1) + inttohex(Rec.DnA[5],1) + ' - Номер абонента А'); //Выводим пакет № 100 memo1.Lines.Add(inttostr(Rec.Np100) + ' - Номер пакета'); memo1.Lines.Add(inttohex(Rec.Date[3],1) +'.'+ inttohex(Rec.Date[2],1) +'.'+ inttohex(Rec.Date[1],1) + ' - Дата'); memo1.Lines.Add(inttostr(Rec.Time[1]) +':'+ inttostr(Rec.Time[2]) +':'+ inttostr(Rec.Time[3]) + ' - Время'); memo1.Lines.Add(inttohex(Rec.Prod[3],1) +':'+ inttohex(Rec.Prod[2],1) +':'+ inttohex(Rec.Prod[1],1) + ' - Продолжительность'); //Выводим пакет № 101 memo1.Lines.Add(inttostr(Rec.Np101) + ' - Номер пакета'); memo1.Lines.Add(inttostr(Rec.LenDnB) + ' - Длина номера абонента Б'); memo1.Lines.Add(inttostr(Rec.DnB[1]) + ' - Номера абонента Б'); //Выводим пакет № 130 memo1.Lines.Add(inttostr(Rec.Np130) + ' - Номер пакета'); memo1.Lines.Add(inttostr(Rec.LenP) + ' - Длина пакета'); memo1.Lines.Add(inttostr(Rec.Zp) + ' - Причина'); memo1.Lines.Add(inttostr(Rec.RezAndOpr) + ' - Резерв и определение'); {end;} CloseFile(f); end;] Как обойти ошибку которая требует финализации переменной f: file of AMA или дайте ссылочку где можно почитать про работу с потоками. Последний раз редактировалось royun, 30.08.2011 в 09:02. |