Function Cjt_LoadFromFile(SourceFile,TargetFile :string):Boolean;
var
Source:TFileStream;
Target:TMemoryStream;
MyFileSize:integer;
begin
try
Target:=TMemoryStream.Create;
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
try
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小
Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置
Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源
Target.SaveToFile(TargetFile);//存放到文件
finally
Target.Free;
Source.Free;
end;
except
Result:=false;
Exit;
end;
Result:=true;
end;
其中参数SourceFile是已经添加了文件的文件名称,参数TargetFile是取出文件后保存的目标文件名
问题:在这里只要定义了MyFileSize:integer,那么无论MyFileSize赋值多少,sizeof(MyFileSize)的值永远为4是吗?
Source.Seek(-sizeof(MyFileSize),soFromEnd); 指针在哪里?在source程序的开头吗?还是指向附加数据的起始?谢谢指教
var
Source:TFileStream;
Target:TMemoryStream;
MyFileSize:integer;
begin
try
Target:=TMemoryStream.Create;
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
try
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小
Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置
Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源
Target.SaveToFile(TargetFile);//存放到文件
finally
Target.Free;
Source.Free;
end;
except
Result:=false;
Exit;
end;
Result:=true;
end;
其中参数SourceFile是已经添加了文件的文件名称,参数TargetFile是取出文件后保存的目标文件名
问题:在这里只要定义了MyFileSize:integer,那么无论MyFileSize赋值多少,sizeof(MyFileSize)的值永远为4是吗?
Source.Seek(-sizeof(MyFileSize),soFromEnd); 指针在哪里?在source程序的开头吗?还是指向附加数据的起始?谢谢指教
即,(-1)*sizeof(MyFileSize)
soFromEnd,即文件末尾
指针在文件末尾,的前sizeof(MyFileSize)个字节。
Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源 说明文件的尾部4个字节保存的值 = 资源所占字节数 + 4
第一:
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));
这句读出的资源大小是文件后面4个字节的资源大小吧(因为sizeof(MyFileSize)是4个字节)?
第二:
Source.Seek(-MyFileSize,soFromEnd);
这句中,变量MyFileSize还没有赋值,怎么就能直接使用了?是不是通过Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));这句给myfilesize赋的值?
从文件中读出4个字节的内容置入MyFileSize变量所在内存处,这样一来,MyFileSize将获得文件尾部的4个字节所代表的Integer值,该值应该等于 资源所占字节数 + 4。
去掉下面两句:
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小
然后直接写成下面的代码:
Source.Seek(-4,soFromEnd);
Target.CopyFrom(Source,MyFileSize-4);
Target.SaveToFile(TargetFile);
感觉那两句好像没什么用,是吗?
....(这里是其它不相关的内容)...|......(这里是有用的内容).....|这里有4个字节存储前面内容的长度|<<此为文件结束符这就是Source的格式。
取出的时候,由于Source包含了需要的和不需要的内容,只知道需要的内容加上四个字节表示的长度信息放在最后面。
因此需要先取出长度,而Stream是顺序读取的,所以需要先偏移到倒数第四(以后可能是八字字节或者其它,所以需要用sizeof)个字节,才能读取出长度
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(...
读取完之后文件偏移已经是文件末尾,所以需要再次移动
Source.Seek(-MyFileSize,soFromEnd);
但是由于读取出来的文件长度,还包含长度信息本身所占的字节数,所以需要长度得扣除该字节数
Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//
这句是指定又移到资源首部了吧
改成这样行否
Source.Seek(0,soFromEnd);
改成这样行否
Source.Seek(0,soFromBeginning);或Source.Position:=0;