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程序的开头吗?还是指向附加数据的起始?谢谢指教

解决方案 »

  1.   

    -sizeof(MyFileSize)
    即,(-1)*sizeof(MyFileSize)
    soFromEnd,即文件末尾
    指针在文件末尾,的前sizeof(MyFileSize)个字节。
      

  2.   

    sizeof 表示求这个数据类型的大小,你的MyFileSize是Integer,而Integer在默认编译器设置下是4个字节,所以值就是4了。你如果知道文件大小,可以直接使用MyFileSize而不用SIZEOF来多此一举了。
      

  3.   

    MyFileSize是Integer类型, 所以在Win32操作系统中sizeof(MyFileSize)的值是4。Source.Seek(-sizeof(MyFileSize),soFromEnd); 执行之后,文件流指针指向文件尾倒数第4个字节处。Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小 , 文件流指针指向文件尾。Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置
    Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源 说明文件的尾部4个字节保存的值 = 资源所占字节数 + 4
      

  4.   

    先谢谢上面几位的帮助~还有两点不明白:
    第一:
    Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));
    这句读出的资源大小是文件后面4个字节的资源大小吧(因为sizeof(MyFileSize)是4个字节)?
    第二:
    Source.Seek(-MyFileSize,soFromEnd); 
    这句中,变量MyFileSize还没有赋值,怎么就能直接使用了?是不是通过Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));这句给myfilesize赋的值?
      

  5.   

    Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));
    从文件中读出4个字节的内容置入MyFileSize变量所在内存处,这样一来,MyFileSize将获得文件尾部的4个字节所代表的Integer值,该值应该等于 资源所占字节数 + 4。
      

  6.   

    我又想了一下,这段代码是不是有些啰嗦?感觉好像2次都把指针定位在了倒数第四个字节处,可不可以
    去掉下面两句:
    Source.Seek(-sizeof(MyFileSize),soFromEnd); 
    Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小 
    然后直接写成下面的代码:
    Source.Seek(-4,soFromEnd);
    Target.CopyFrom(Source,MyFileSize-4);
    Target.SaveToFile(TargetFile);
    感觉那两句好像没什么用,是吗?
      

  7.   

    还是请楼主先弄明白是怎么一回事:
    ....(这里是其它不相关的内容)...|......(这里是有用的内容).....|这里有4个字节存储前面内容的长度|<<此为文件结束符这就是Source的格式。
    取出的时候,由于Source包含了需要的和不需要的内容,只知道需要的内容加上四个字节表示的长度信息放在最后面。
    因此需要先取出长度,而Stream是顺序读取的,所以需要先偏移到倒数第四(以后可能是八字字节或者其它,所以需要用sizeof)个字节,才能读取出长度
    Source.Seek(-sizeof(MyFileSize),soFromEnd);
    Source.ReadBuffer(...
    读取完之后文件偏移已经是文件末尾,所以需要再次移动
    Source.Seek(-MyFileSize,soFromEnd);
    但是由于读取出来的文件长度,还包含长度信息本身所占的字节数,所以需要长度得扣除该字节数
    Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//
      

  8.   

    仔细想了一下,终于想明白了,谢谢unsigned 和jadeluo 的解答!
      

  9.   

    Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置
    这句是指定又移到资源首部了吧
      

  10.   

    指定=指针
    改成这样行否
    Source.Seek(0,soFromEnd);
      

  11.   

    Source.Seek(-MyFileSize,soFromEnd);
    改成这样行否
    Source.Seek(0,soFromBeginning);或Source.Position:=0;