先看代码,这是个自己定义的函数:
function MyLoadFromFile(SourceFile,TargetFile :string):Boolean;
var
  Source:TFileStream;
  Target:TMemoryStream;
  MyFileSize:integer;//问题就是这个变量
begin
  try
    Target:=TMemoryStream.Create;
    Source:=TFileStream.Create(SourceFile,fmOpenRead);
    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;下面是问题:
问题一:
MyFileSize这个integer类型的变量,并没有显性的赋给初值,但是执行这个程序的时候,在Source.Seek(-sizeof(MyFileSize),soFromEnd);这个语句执行时(也就是第一句),它就有了值,不是0哦,是一个不小的数字,一次是17,一次是400000多,不知道是不是巧合,和我想操作的文件大小差不许多;不知道这个数字是怎么来的.我以前是用java语言的,java中int类型如果不赋初值,系统会默认初值是0,不知道delphi是否有默认初值这一说法,或者那初值是怎么来的,灵异事件???
问题二:
在这段程序中,MyFileSize这个变量被各种玩弄,不停的被拿来使用,我本来想用单步运行来看看它的值是怎么变化的,结果上来那个初值就给我整蒙了,请哪位高手给小弟解释一下MyFileSize这个参数的值到底每一步都代表了啥,555
ps:感觉这个要求有些过分,如果大侠们觉得这个要求很不爽,当然可以不回答这第二个问题,它不是我疑惑的主要问题
问题三:
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));
这个方法的定义是Procedure ReadBuffer(var Buffer;Count:Longint);
其中参数Buffer我一直理解不好,因为程序是用Integer类型变量来做这个Buffer的;我在网上查询缓冲,也没弄明白缓冲到底是怎么个东西,它可以用什么类型的变量来做,请各位大侠解释一下~(感觉这个问题比我第二个问题上路吧?)最后说明一下这段代码是做什么的,我看的一个stream操作例子,是将一个文件写入另一个文件尾部,然后再读取出来的例子,号称为文件的加密解密.上面提供的代码是解密代码,我再将加密代码贴出来.
Function MyAddtoFile(SourceFile,TargetFile:string):Boolean;
var
  Target,Source:TFileStream;
  MyFileSize:integer;
begin
  try
    Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);
    Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);
    try
      Target.Seek(0,soFromEnd);//往尾部添加资源
      Target.CopyFrom(Source,0);
      MyFileSize:=Source.Size+Sizeof(MyFileSize);//计算资源大小,并写入辅程尾部
      Target.WriteBuffer(MyFileSize,sizeof(MyFileSize));
    finally
      Target.Free;
      Source.Free;
    end;
  except
    Result:=False;
    Exit;
  end;
  Result:=True;
end;还有,这个加密代码运行正确,而那个解密代码运行报错,问题就是出在那诡异的MyFileSize变量上...
背后发凉,这个问题怎么问得象鬼故事呢~~盼望大家早日为小弟解答心中疑惑

解决方案 »

  1.   

    回答问题一:在delphi的函数里的临时变量,如果没有赋值,则这个变量是个随机值。Delphi不会自动赋初值。
      

  2.   

    问题二:这个程序不是你写的吧。什么含义都没有搞清楚。这个值在这里的意思应该是资源文件本身的大小。这段代码是把附加在一个文件上(sourcefile)的另一个文件解出来,存为targefile。
      

  3.   

    buffer的意思就是一片内存。
    比如:Source.ReadBuffer(MyFileSize,sizeof(MyFileSize))
    表示,读入sizeof(MyFileSize)个长度的字节数到MyFileSize这个地址的内存中。
    如果你学了C语言指针的话,这个很好理解的。
      

  4.   

    非常感谢回答,第一个问题明白了,果然很奇怪.
    第二个问题,整个程序确实不是我写的,不过我记得好像声明过了,呵呵,不过这不是问题关键啦.其实这个代码我知道他想干嘛,我疑惑的是这三行代码:
          Source.Seek(-sizeof(MyFileSize),soFromEnd);
          Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小
          Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置
    我就不明白为什么对MyFileSize不赋初值,然后直接拿来用,就可以得到之前存在文件尾的信息,即资源大小.
    第三个问题,它是什么我明白了,多谢~ 现在我的问题是,什么类型可以用来做这个缓存呢??比如这个例子中用的就是Integer类型,一定要用这个类型么?String可以么?PChar可以么?数组可以么?象keyz(keyz) 兄所说,读出的数据是放在了那个变量地址的内存中,那么我的问题是:
    这个变量是否是用变量本身来承接这个缓冲数据,即类似:变量:=缓冲数据
    还是将缓冲数据放在了这个变量的地址中,这个变量成了一个指针,那为什么不用@变量,
    或者变量^
    还是这个变量当时的值记录了它所在的内存地址,5555,我混乱了~非常感谢回答,非常感谢.
    我的回复不是抬杠,不是怀疑,是真的不懂,真的不懂,请指教,多谢~多谢~~
      

  5.   


    Source.Seek(-sizeof(MyFileSize),soFromEnd);
    这个是把流的指针指向流最后的4个字节,sizeof(MyFileSize)是4,返回的是integer类型大小Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小
    这个是读入4个字节到MyFileSize中。其实就是赋值了。=============
    基本上任何类型都可以作为buffer。String和PChar都可以,实事上也经常作为buffer使用。但是string和pchar在使用前都要分配内存。如 s:=stringofchar(' ',100),把一个100个字符空格的字符串赋给s。但是在调用readbuffer之类的时候,要使用 s[1],或者 p^ 这样的形式,否则的话,传过去的值将是指针的指针。很容易就发生内存读写错误。
     
    实施上使用了关键字 var 来传输变量,在内部就是传送了指定变量的指针。所以不用@简单的理解,readbuffer这样的函数就是把stream中对应的数据放到buffer这个变量所在的地址中,放的数量为Count个数量的Byte.有兴趣的话,在Delphi中,按住Ctrl,点击readbuffer,可以看到delphi是如何实现这个函数的。