最近碰到一个问题,我要做一个软件的安装程序,需要在安装的时候播放flash的动画,完全用flash做安装界面,没有现成的安装工具可以使用。于是决定自己写一个安装程序。初步决定的方案是用zipforge来解压缩附在一个exe尾巴上的zip文件以实现软件安装。但是这就需要zipforge从一个大文件的中间开始解压缩zip,而不是从开头。
因为文件比较大(大约425M),所以加载进内存进行分割是不现实的,而且这样也会浪费内存或者硬盘空间,zipforge可以从一个stream中解压文件,可是filestream无法实现偏移读取,我想从Tfilestream继承一个新类来实现偏移读取文件的开端,但是不知道给怎么实现。请大家给些建议,谢谢了!

解决方案 »

  1.   

    谁说TFileStream不能偏移读取?
    procedure TForm1.Button1Click(Sender: TObject);
    var
      vBuffer: array[0..255] of Char;
    begin
      with TFileStream.Create(ParamStr(0), fmShareDenyNone) do try
        Seek($50, soBeginning);
        Read(vBuffer, SizeOf(vBuffer));
        ShowMessage(vBuffer);
      finally
        Free;
      end;
    end;
      

  2.   

    楼上没看明白我的意思,因为我要用zipforge解压缩,所以这个filestream不是我自己写代码读取,而是zipforge控件自己来读取,期间的细节我不能控制,zipforge控件可不知道需要从制定的字节开始算起,它只会从position:=0的地方开始解压然后解不开报错。编译以后的exe文件大小差不多是固定的,偏移量比较好算,制作不同的安装文件也只要copy /b projiect1.exe+压缩包.zip 一个copy命令就好了。425Mb 的资源文件,也太夸张了一点。
    最好的办法还是把zipforge骗过去,代价最小,就是对继承不太熟而已。
      

  3.   

    简单一点,可以自己先把zipforge需要的部分截出来保存到temp目录下。
      

  4.   

    procedure TForm1.CutFileData;
    var
      AReadStream:TFileStream;
      Buf:Array[0..127] of Byte;
      CurPos:Int64;
      ReadCount,J:Integer;
      str:string;  //把数组buf里的数据用string表示
    begin
      Datalist:=Tstringlist.Create;
      begin
      AReadStream:=TFileStream.Create(loadfilename,fmOpenRead);
      try
        AReadStream.Position:=0;
        CurPos:=0;
        While CurPos<AReadStream.Size do
          begin
            str:='';
            ReadCount:=AReadStream.Read(Buf,64);
            if ReadCount<=0 then Break;
               for J:=0 to 63 do            // 将数据写到TstringList 里
                 str:=str+BytetoHex(Buf[J]);
            DataList.add(str);
            CurPos:=CurPos+64; //偏移量为64字节
          end;
      finally
        AReadStream.Free;
      end;
     end;
    end;
    记得给加分啊 
      

  5.   

    如果你非要用继承的话,可以这样试试:TOffSetFileStream = class(TFileStream)
    private
      fOffset: Integer;  // 用来保存偏移地址
    public
      function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
    end;function TOffSetFileStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
    begin
      if Origin = soBeginning then
        Result := inherited Seek(Offset + fOffset, Origin)
      else
        Result := inherited Seek(Offset, Origin);
    end;