关于Delphi对二进制文件(.bin文件)的读写操作

时间:2021-07-19 11:47:56
最近需要写个U盘升级程序,从而开始接触Delphi7.
   请问下,Delphi对二进制文件的读写是怎么样的一个过程,能写个有注释的代码吗?
具体的要求是这样的:
  firmware.bin 文件里有个结构体
     typedef struct S_FIRMWARE_BIN_TAG{
U32 iBinFileLen; //the length of the binary
U8 xMd5Checksum[256]; // (128k(max firmware size)/8k(md5 input size) )*16bytes 
//(md5 output size)
U8 iVersion_main; //number
U8 iVersion_major; // number
U8 iVersion_minor; // number
U8 cVersion_fix; //character like a, b ,c .etc
U8 cProductId[16]; //string
U8 cVendorId[16]; //string
U8 cCustomer[16]; //string
U8 cDescription[200]; //string
         } FIRMWARE_BIN_TAG

现在,在一个事件中需要对这个.bin文件进行读写操作,并将字符串数组cproductID,cvendorID,( iVersion_main.iVersion_major.cVersion_minor)赋值给char a,b and c(都是char哈!).
   希望大家不要闲分少哈,本人菜鸟一个~~~

11 个解决方案

#1




type
FIRMWARE_BIN_TAG = record
iBinFileLen:integer;
xMd5Checksum:array[0..255]of byte;
iVersion_main:byte;
iVersion_major:byte;
iVersion_minor:byte;
cProductId:array[0..15]of byte;
cVendorId:array[0..15]of byte;
cCustomer:array[0..15]of byte;
cDescription:array[0..199]of byte;
end;


var
x:FIRMWARE_BIN_TAG;
h:Integer;
  str:string;
begin

h := FileOpen( 'test' , fmOpenRead  );
  FileRead( h , x , SizeOf(x) );
  str := Pchar(@x.cProductId);
  writeln(str);
end.

#2


如果支持C的话,那就是
char *tmp;
tmp=malloc(sizeof(FIRMWARE_BIN_TAG ));//申请内存空间。

FILE *pfile=fopen("文件名","rb");//打开文件
fread(tmp,sizeof(FIRMWARE_BIN_TAG ),1,pfile);//读文件

char *offset;
offset=tmp+sizeof(u32)+sizeof(u8)*256+sizeof(u8)*4;//cproductID偏移字节数

 char a[17]//我是按u8=1个byte算的。17=sizeof(u8)*16+1
for(int i=0;i<16;i++)//赋值给char a[]
a[i]=*offset;
a[16]='\0';

offset=offset+16;//偏移到cvendorID

char b[17];
for(int i=0;i<16;i++)//赋值给char b[]
b[i]=*offset
b[16]='\0';

#3


代码如下:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;



type S_FIRMWARE_BIN_TAG=packed record
iBinFileLen: int64 ;
xMd5Checksum:array [0..256-1] of byte;
iVersion_main:Byte ;
iVersion_major:Byte ;
iVersion_minor:Byte ;
cVersion_fix:Byte;
cProductId:array [0..16-1] of char ;
cVendorId:array [0..16-1] of char ;
cCustomer:array [0..16-1] of char ;
cDescription:array [0..200-1] of char ;
end;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var Fhandle:THandle;
var buff:S_FIRMWARE_BIN_TAG;
var readcount:Cardinal ;
var a,b,c:string;
begin

  Fhandle:=CreateFile(pchar('firmware.bin'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

  ReadFile(Fhandle,buff,SizeOf (S_FIRMWARE_BIN_TAG),readcount,nil)  ;

  a:=buff.cProductId;
  b:=buff.cvendorID;
  c:= inttostr(buff.iVersion_main)+'.'+inttostr(buff.iVersion_major)+'.'+inttostr(buff.iVersion_minor) ;


end;

end.

#4


抱歉 ,iBinFileLen: int64 ; 应为 iBinFileLen: integer ;

#5


先谢谢大家了,我再细看哈!

#6


itmes 同学给的东西很好,不过我看是看不懂,运行了一下,也不是很理想.但不管怎么样,还是要谢谢了!

#7


晕,再没人指教下啊!!哭啊

#8


引用 7 楼 littler_winds 的回复:
晕,再没人指教下啊!!哭啊

指教?不敢当.楼主是想问如何读写呢,还是想要源代码?如果是的话那就发到 http://prj.csdn.net

#9


更新下,结构体为:

type S_FIRMWARE_BIN_TAG=packed record
iVersion_main:byte;
iVersion_major:byte;
iVersion_minor:byte;
cVersion_fix:byte;
  cUsrPasswd:array[0..16] of char;
  cBT_nickname:array[0..40] of char;
iUpgradeStatus:char;
end;

现在在Delphi界面的相应位置想显示出version information和nickname ,格式分别为:
 version information:  byte(main).byte(major).byte(minor)byte(fix) 
如version information:1.2.3a
 nickname: str()  如 nickname:abcddd


另上面几为朋友给出的代码或多或少出现了问题,我在上面说个.但还是非常感谢他们的帮助.

#10


type
  S_FIRMWARE_BIN_TAG = record 
    iBinFileLen:LongWord; //the length of the binary 
    xMd5Checksum: array[0..256-1] of Byte; // (128k(max firmware size)/8k(md5 input size) )*16bytes 
//(md5 output size) 
    iVersion_main: Byte; //number 
    iVersion_major: Byte; // number 
    iVersion_minor: Byte; // number 
    cVersion_fix: Char; //character like a, b ,c .etc 
    cProductId: String[16]; //string 
    cVendorId: String[16]; //string 
    cCustomer: String[16]; //string 
    cDescription: String[200]; //string 
end;
FIRMWARE_BIN_TAG = S_FIRMWARE_BIN_TAG

#11


不错,让俺又学了一招!

#1




type
FIRMWARE_BIN_TAG = record
iBinFileLen:integer;
xMd5Checksum:array[0..255]of byte;
iVersion_main:byte;
iVersion_major:byte;
iVersion_minor:byte;
cProductId:array[0..15]of byte;
cVendorId:array[0..15]of byte;
cCustomer:array[0..15]of byte;
cDescription:array[0..199]of byte;
end;


var
x:FIRMWARE_BIN_TAG;
h:Integer;
  str:string;
begin

h := FileOpen( 'test' , fmOpenRead  );
  FileRead( h , x , SizeOf(x) );
  str := Pchar(@x.cProductId);
  writeln(str);
end.

#2


如果支持C的话,那就是
char *tmp;
tmp=malloc(sizeof(FIRMWARE_BIN_TAG ));//申请内存空间。

FILE *pfile=fopen("文件名","rb");//打开文件
fread(tmp,sizeof(FIRMWARE_BIN_TAG ),1,pfile);//读文件

char *offset;
offset=tmp+sizeof(u32)+sizeof(u8)*256+sizeof(u8)*4;//cproductID偏移字节数

 char a[17]//我是按u8=1个byte算的。17=sizeof(u8)*16+1
for(int i=0;i<16;i++)//赋值给char a[]
a[i]=*offset;
a[16]='\0';

offset=offset+16;//偏移到cvendorID

char b[17];
for(int i=0;i<16;i++)//赋值给char b[]
b[i]=*offset
b[16]='\0';

#3


代码如下:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;



type S_FIRMWARE_BIN_TAG=packed record
iBinFileLen: int64 ;
xMd5Checksum:array [0..256-1] of byte;
iVersion_main:Byte ;
iVersion_major:Byte ;
iVersion_minor:Byte ;
cVersion_fix:Byte;
cProductId:array [0..16-1] of char ;
cVendorId:array [0..16-1] of char ;
cCustomer:array [0..16-1] of char ;
cDescription:array [0..200-1] of char ;
end;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var Fhandle:THandle;
var buff:S_FIRMWARE_BIN_TAG;
var readcount:Cardinal ;
var a,b,c:string;
begin

  Fhandle:=CreateFile(pchar('firmware.bin'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

  ReadFile(Fhandle,buff,SizeOf (S_FIRMWARE_BIN_TAG),readcount,nil)  ;

  a:=buff.cProductId;
  b:=buff.cvendorID;
  c:= inttostr(buff.iVersion_main)+'.'+inttostr(buff.iVersion_major)+'.'+inttostr(buff.iVersion_minor) ;


end;

end.

#4


抱歉 ,iBinFileLen: int64 ; 应为 iBinFileLen: integer ;

#5


先谢谢大家了,我再细看哈!

#6


itmes 同学给的东西很好,不过我看是看不懂,运行了一下,也不是很理想.但不管怎么样,还是要谢谢了!

#7


晕,再没人指教下啊!!哭啊

#8


引用 7 楼 littler_winds 的回复:
晕,再没人指教下啊!!哭啊

指教?不敢当.楼主是想问如何读写呢,还是想要源代码?如果是的话那就发到 http://prj.csdn.net

#9


更新下,结构体为:

type S_FIRMWARE_BIN_TAG=packed record
iVersion_main:byte;
iVersion_major:byte;
iVersion_minor:byte;
cVersion_fix:byte;
  cUsrPasswd:array[0..16] of char;
  cBT_nickname:array[0..40] of char;
iUpgradeStatus:char;
end;

现在在Delphi界面的相应位置想显示出version information和nickname ,格式分别为:
 version information:  byte(main).byte(major).byte(minor)byte(fix) 
如version information:1.2.3a
 nickname: str()  如 nickname:abcddd


另上面几为朋友给出的代码或多或少出现了问题,我在上面说个.但还是非常感谢他们的帮助.

#10


type
  S_FIRMWARE_BIN_TAG = record 
    iBinFileLen:LongWord; //the length of the binary 
    xMd5Checksum: array[0..256-1] of Byte; // (128k(max firmware size)/8k(md5 input size) )*16bytes 
//(md5 output size) 
    iVersion_main: Byte; //number 
    iVersion_major: Byte; // number 
    iVersion_minor: Byte; // number 
    cVersion_fix: Char; //character like a, b ,c .etc 
    cProductId: String[16]; //string 
    cVendorId: String[16]; //string 
    cCustomer: String[16]; //string 
    cDescription: String[200]; //string 
end;
FIRMWARE_BIN_TAG = S_FIRMWARE_BIN_TAG

#11


不错,让俺又学了一招!