怎么把一个如下record 的数据读到一个流文件里,保存到问题;又能顺利的从文件中读取record的数据
TFileMessage= record
FileName:AnsiString;
ISize:Int64;
end;
TFiles=array of TFileMessage;
TGZHeader = record
Id1 : Byte;
Id2 : Byte;
Method : Byte;
Flags : Byte;
Time : Cardinal;
ExtraFlags: Byte;
OS : Byte;
password:string;
Files:TFiles;
end;现在我碰到的问题,能读进去,但是流文件保存成文件后,再读取出来,files的信息就没法正常显示。
TFileMessage= record
FileName:AnsiString;
ISize:Int64;
end;
TFiles=array of TFileMessage;
TGZHeader = record
Id1 : Byte;
Id2 : Byte;
Method : Byte;
Flags : Byte;
Time : Cardinal;
ExtraFlags: Byte;
OS : Byte;
password:string;
Files:TFiles;
end;现在我碰到的问题,能读进去,但是流文件保存成文件后,再读取出来,files的信息就没法正常显示。
解决方案 »
- 如何在程序出错后继续运行出错的代码后面的代码?
- Delphi怎么设置日期格式,如Sunday,November 27,2005?
- 如何设置LABEL 让LABEL可以选择
- ◆◆我编的进销存源码◆◆◆
- [难题,高手请进]为什么TField的DefaultExpression在TQUERY中不起作用?
- 求救,,,BDE问题!!!
- 关于TQuery的问题,急,sos!
- 在2000/xp下怎么注册一个服务程序?
- 为什么我用ADO连接ACCESS的数据库,明明没有设密码,但在程序运行时,总是弹出个用户名、密码框?
- 哪位大大可以解释下PChar的一些转换
- 有谁用过tesseract-ocr开源吗?
- 关于播放器的开发
strstream:TStream;
infilestream,outfilestream:TStream;
myfile,myfile1:TGZHeader;
isize:int64;
i:integer;
begin
myfile.id1:=1;
myfile.Id2:=2;
myfile.Method:=3;
myfile.Flags:=4;
myfile.Time:=5;
myfile.ExtraFlags:=6;
myfile.OS:=7;
myfile.password:='abcdefg'; SetLength(myfile.files,2);
myfile.files[0].FileName:='124.txt';
myfile.files[0].ISize:=26; myfile.files[1].FileName:='4567.txt';
myfile.files[1].ISize:=231; outfilestream:=TFileStream.Create('d:\压缩.szip',fmCreate); //取得长度
isize:=SizeOf(myfile.Id1)+sizeof(myfile.Id2)+sizeof(myfile.Method)+
SizeOf(myfile.Flags)+sizeof(myfile.Time)+sizeof(myfile.ExtraFlags)+
SizeOf(myfile.OS);
strstream:=TStringStream.Create(myfile.password);
isize:=isize+strstream.Size; strstream:=TStringStream.Create(myfile.Files[0].FileName);
isize:=isize+strstream.Size+sizeof(myfile.Files[1].ISize); strstream:=TStringStream.Create(myfile.Files[1].FileName);
isize:=isize+strstream.Size+sizeof(myfile.Files[1].ISize); strstream.Free;
outfilestream.Write(isize,SizeOf(isize));
outfilestream.Write(myfile,isize);
outfilestream.Position:=0;
//直接这样读是没问题
{
infilestream:=TMemoryStream.Create; infilestream.CopyFrom(outfilestream,0); isize:=0;
infilestream.Position:=0;
infilestream.Read(isize,SizeOf(isize));
infilestream.Read(myfile1,isize);
infilestream.Free;
}
outfilestream.Free;
//从文件读就是有问题,具体就是files那里要么是乱七八糟的信息,要么就是为空
{
isize:=0;
infilestream:=TFileStream.Create('d:\压缩.szip',fmOpenRead or fmShareDenyNone);
infilestream.Read(isize,SizeOf(isize));
infilestream.Read(myfile1,isize);
infilestream.Free;
}代码比较乱
Files:TFiles;这两个定义,其实是两个指针,SizeOf(password)=4 SizeOf(Files)=4,它们指向的数据都在其它地方.进行内存复制 CopyFrom这些操作操作的时候,你操作的一定要是全部的实际的数据才行。你不能说我将图书馆的查询标签全程搬走了,就代表将所有的书都搬走了。
先将 password:string; 定义为 password:Array[0..127] of Char; 这个长度应该足够了。
然后将 Files:TFiles;定义原理 Files:Byte;//这仅是代表你的文件的第一个字节从这里开始。TFileMessage.FileName:AnsiString; 这也搞成
TFileMessage.FileName:Array [0..255] of Char; 文件名长度不够的话在加比如你要保存 100个 TFileMessage,它的总长度=Sizeof(TFileMessage)*100;var
Arr:Array of Byte;
ArrLen:Integer;
begin
ArrLen:=Size(TGZHeader )+Sizeof(TFileMessage)*100 -1;
减一的原因是 你的 TFiles 将从 Files:Byte;这个位置开始。 Setlength(Arr,Arrlen);//这个长度的内存块将保存你所有的数据。
接下来就是将这个内存块复制到流中了。end;
你保存是应该不能用 TStream 吧,应该用TMemoryStream.
也没有必要在定义Arr,直接给 TMemoryStream设置长度,将数据写入就可以了。end;你可以看一下:
http://topic.csdn.net/u/20110910/00/3d45c96b-0133-4f13-b806-6b26715a39f4.html
关于内存和指针操作,数据类型转换本质的理解
你好,非常感谢你的解答,我按照你的做法,一个个都重新定义成定长,在最后取的时候我本来想算出长度直接取整个files 的数据,但发现取出来的数据都是错误的。但如果我 files 数组做循环,一个个取里面的record 的数据,这样是正确的。能否告知为什么整个取是错误的呢? 谢谢。
你好,非常感谢你的解答,我按照你的做法,一个个都重新定义成定长,在最后取的时候我本来想算出长度直接取整个files 的数据,但发现取出来的数据都是错误的。但如果我 files 数组做循环,一个个取里面的record 的数据,这样是正确的。能否告知为什么整个取是错误的呢? 谢谢。
流的前面保存的是 TGZHeader 结构的数据。要读也是这样你要先将流的指针位置移动到 TGZHeader 结构 Files 的位置,然后在取。
var
infilestream:TStream;
isize:Int64;
i:Integer;
myfile:TGZHeader;
file1:TFiles;
begin
infilestream:=TFileStream.Create('d:\压缩.szip',fmOpenRead or fmShareDenyNone);
//先读tgzheader大小
infilestream.Read(myfile,SizeOf(TGZHeader));
i:=myfile.Files;//这个是记录files 长度的元素,在读入流的时候记录在Tgzheader的 这个元素中
SetLength(file1,myfile.Files);
isize:=i*sizeof(tfilemessage);//算总的files 长度
//这是一个个读取,读取出来的数据正常
{
for I := 0 to myfile.Files-1 do infilestream.ReadBuffer(file1[i],SizeOf(tfilemessage));
}
infilestream.Read(file1[0],isize);
infilestream.Free;