(300分)求救高手:记录类型文件读取错误(300分)

  • 主题发起人 主题发起人 lodgue
  • 开始时间 开始时间
L

lodgue

Unregistered / Unconfirmed
GUEST, unregistred user!
首先贴出元代码:<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, Buttons,ShareTools;<br><br>type<br><br>&nbsp; TTestStruct=record<br>&nbsp; &nbsp; aInt:integer;//4<br>&nbsp; &nbsp; bDouble:double;//8<br>&nbsp; &nbsp; cInt:integer;//4<br>&nbsp; end;<br><br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; SaveToFile: TButton;<br>&nbsp; &nbsp; ReadByRecord: TButton;<br>&nbsp; &nbsp; ReadByByte: TSpeedButton;<br>&nbsp; &nbsp; procedure SaveToFileClick(Sender: TObject);<br>&nbsp; &nbsp; procedure ReadByByteClick(Sender: TObject);<br>&nbsp; &nbsp; procedure ReadByRecordClick(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>const<br>&nbsp; FileName:string='/test.dat';<br>&nbsp; TrueFalse:array [0..1] of string=('False','True');<br>procedure SetTestStruct(var ts:TTestStruct);<br>begin<br>&nbsp; ts.aInt:=100;<br>&nbsp; ts.bDouble:=3.14;<br>&nbsp; ts.cInt:=5;<br>end;<br>procedure SaveStructToFile(const ts:TTestStruct);<br>var<br>&nbsp; hFile:THandle;<br>&nbsp; ExeDir,FullFileName:string;<br>begin<br>&nbsp; ExeDir:=ExtractFileDir(ParamStr(0));<br>&nbsp; FullFileName:=ExeDir+FileName;<br>&nbsp; if not FileExists(FullFileName) then<br>&nbsp; &nbsp; hFile:=FileCreate(FullFileName)<br>&nbsp; else<br>&nbsp; &nbsp; hFile:=FileOpen(FullFileName,fmOpenReadWrite);<br>&nbsp; if hFile&lt;=0 then Raise Exception.Create('打开文件出错');<br>&nbsp; try<br>&nbsp; &nbsp; FileSeek(hFile,0,2);<br>&nbsp; &nbsp; FileWrite(hFile,ts,SizeOf(ts));<br>&nbsp; finally<br>&nbsp; &nbsp; FileClose(hFile);<br>&nbsp; end;<br>end;<br><br>procedure TForm1.SaveToFileClick(Sender: TObject);<br>var<br>&nbsp; ts:TTestStruct;<br>begin<br>&nbsp; SetTestStruct(ts);<br>&nbsp; SaveStructToFile(ts);<br>end;<br><br>procedure TForm1.ReadByByteClick(Sender: TObject);<br>var<br>&nbsp; hFile:THandle;<br>&nbsp; ExeDir,FullFileName:string;<br>&nbsp; aInt:integer;<br>&nbsp; bDouble:double;<br>&nbsp; cInt:integer;<br>begin<br>&nbsp; ExeDir:=ExtractFileDir(ParamStr(0));<br>&nbsp; FullFileName:=ExeDir+FileName;<br>&nbsp; if FileExists(FullFileName) then begin<br>&nbsp; &nbsp; hFile:=FileOpen(FullFileName,fmOpenRead);<br>&nbsp; &nbsp; if hFile&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; FileRead(hFile,aInt,4);<br>&nbsp; &nbsp; &nbsp; &nbsp; FileSeek(hFile,4,1);<br>&nbsp; &nbsp; &nbsp; &nbsp; FileRead(hFile,bDouble,8);<br>&nbsp; &nbsp; &nbsp; &nbsp; FileSeek(hFile,8,1);<br>&nbsp; &nbsp; &nbsp; &nbsp; FileRead(hFile,cInt,4);<br>&nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; FileClose(hFile);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.ReadByRecordClick(Sender: TObject);<br>var<br>&nbsp; hFile:THandle;<br>&nbsp; ExeDir,FullFileName:string;<br>&nbsp; ts:TTestStruct;<br>begin<br>&nbsp; ExeDir:=ExtractFileDir(ParamStr(0));<br>&nbsp; FullFileName:=ExeDir+FileName;<br>&nbsp; if FileExists(FullFileName) then begin<br>&nbsp; &nbsp; hFile:=FileOpen(FullFileName,fmOpenRead);<br>&nbsp; &nbsp; if hFile&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; FileRead(hFile,ts,SizeOf(ts));<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br>end.
 
问题:<br>&nbsp; 我用安记录方式读取文件没问题(ReadByRecordClick):<br>1: &nbsp;如果使用安字节方式读取出错(ReadByByteClick):<br>&nbsp; 最后一个整形数(cInt)读出来为518(实际上为5)<br>&nbsp; why?????????<br>下面时生成的Test.Dat文件中的HEX Code:<br><br>00000000h &nbsp;64 00 00 00 76 00 00 00 1F 85 EB 51 B8 1E 09 40;<br>00000010h &nbsp;05 00 00 00 07 00 00 00<br><br>2 SizeOf(Double)=8,为什么在Test.Dat中占12个字节<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(76 00 00 00 1F 85 EB 51 B8 1E 09 40).<br><br>3.为什么在最后要添加07 00 00 00 <br><br>4. 如果将cInt去掉或加上dInt记录成员(假如=1)则结果分别为:<br><br>cInt去掉 :<br>&nbsp; 00000000h &nbsp;64 00 00 00 76 00 00 00 1F 85 EB 51 B8 1E 09 40;<br>&nbsp; <br>dInt加上:(=1)<br>&nbsp; 00000000h &nbsp;64 00 00 00 76 00 00 00 1F 85 EB 51 B8 1E 09 40;<br>&nbsp; 00000010h &nbsp;05 00 00 00 01 00 00 00<br>&nbsp; why??
 
我大概明白了:<br>这和Delphi的编译器指令有关{$A+}{$A-}<br>{$A+} - 对齐没有使用Packed关键字的字段中的域(填充一些随机值)<br>{$A-} - 不使用对齐保存数据.和使用Packed关键字描述的结果一样.<br>同样,<br>在Delphi的设置中可以进行设置.project/options/complier中Code Generation中的<br>aligned record fields
 
一般都用上packed。
 
明白了就自己结束吧,结构的对齐方式有多种,不同的编译器是不同的。<br>目前的操作系统一般都要求对齐的。
 
300分,丢了,丢了,可惜,可惜!<br>强烈建议,可以捡回分数的功能
 
Integer:为整型的定义,在不同的DELPHI版本中是不一样的,16位版本(如:DELPHI 1.0)的整型为即Smallint;<br>在32位版本(如:DELPHI3,DELPHI4,DELPHI5)的整型为Longint;DELPHI 2.0为16位和32位的过渡版本。<br>因我未用DELPHI6,不知其是多少位的定义。<br>关于对齐,可用以下方式定义避免:<br>TTestStruct= packed record<br>&nbsp; &nbsp; aInt:Longint;//4<br>&nbsp; &nbsp; bDouble:double;//8<br>&nbsp; &nbsp; cInt:Longint;//4<br>&nbsp; end;<br><br><br>
 
你以前是学C的吧!<br>在Delphi中,用f : file of byte;<br>用BLOCKREAD,BLOCKWRITE读写文件很方便,相关函数ASSIGNFILE,RESET,REWRITE<br>你看一下帮助,象你的这个程序,几句话就完了
 
太可怜了,写这么个简单东西居然用了这么多代码,而且还不好读
 
&gt;&gt;lodgue<br>其实你在使用C的思想来解决delphi的问题;<br>
 
哎,白送分了!
 
我也在做读写记录的程序,看了有所启发, lodgue你的分没有白送<br><br>不过我的分也不多,我也要分
 
后退
顶部