zoukankan      html  css  js  c++  java
  • 实用控件:将任意文件打包进dfm(zlib压缩)的控件 [转]

    来源:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3263037

    该控件可以将任意文件打包进.dfm(使用zlib压缩),可以用该控件编写只有一个exe的绿色软件,或者用于自己编写安装程序。
    使用非常简单,设计期将该控件放入form, 指定FileName属性即可将该文件内容打包进dfm中。运行时可以调用FileRes1.ResToFile解压到指定的文件内或通过FileRes1.ResToStream解压到一个stream中(比如图片文件,接下去可以用Bitmap.LoadFromStream读入),这两个函数的Keep参数指定是否在操作的同时释放FileRes中占用的内存(如果只需要在程序运行时解压一次则建议使用Keep := False; 这样可以降低程序占用的内存)
    unit FileRes;
    interface
    uses
      SysUtils, Classes, Windows, ZLib;
    type
      TBufferStream = class(TStream)
      private
        FLen: Cardinal;
        FBuffer: Pointer;
        FPosition: Cardinal;
      protected
        procedure SetSize(NewSize: Longint); override;
      public
        destructor Destroy; override;
        function Read(var Buffer; Count: Longint): Longint; override;
        function Seek(Offset: Longint; Origin: Word): Longint; override;
        function Write(const Buffer; Count: Longint): Longint; override;
        procedure SaveToFile(FileName: string);
        procedure LoadFromFile(FileName: string);
        function SaveToStream(Stm: TStream): Integer;
        procedure LoadFromStream(Stm: TStream);
        function ReadString: string;
        procedure Writestring(const Str: string);
        procedure ExchangeBuffer(var ABuffer: Pointer; var ALen: Integer);
        property Buffer: Pointer read FBuffer;
      end;
      TFileRes = class(TComponent)
      private
        { Private declarations }
        FStream: TBufferStream;
        FFileName: TFileName;
        procedure WriteFileData(Stm: TStream);
        procedure ReadFileData(Stm: TStream);
        procedure SetFileName(const Value: TFileName);
      protected
        { Protected declarations }
        procedure DefineProperties(Filer: TFiler); override;
      public
        { Public declarations }
        destructor Destroy; override;
        function ResToFile(AFileName: string; Keep: Boolean = false): Boolean;
        function ResToStream(var Stm: TStream; Keep: Boolean = false): Boolean;
        property Stream: TBufferStream read FStream;
      published
        { Published declarations }
        property FileName: TFileName read FFileName write SetFileName;
      end;
    procedure Register;
    implementation
    procedure Register;
    begin
      RegisterComponents('Standard', [TFileRes]);
    end;
    { TBufferStream }
    destructor TBufferStream.Destroy;
    begin
      reallocmem(fbuffer, 0);
      inherited;
    end;
    procedure TBufferStream.ExchangeBuffer(var ABuffer: Pointer;
      var ALen: Integer);
    var
      tmp: Integer;
    begin
      tmp := Integer(ABuffer);
      ABuffer := FBuffer;
      FBuffer := Pointer(tmp);
      tmp := ALen;
      ALen := FLen;
      FLen := tmp;
      if FPosition > FLen then FPosition := FLen;
    end;
    procedure TBufferStream.LoadFromFile(FileName: string);
    var
      fid: Integer;
    begin
      reallocmem(fbuffer, 0);
      flen := 0;
      fid := fileopen(filename, fmOpenRead or fmShareDenyNone);
      if fid < 0 then exit;
      flen := getfilesize(fid, nil);
      reallocmem(fbuffer, flen);
      fileread(fid, fbuffer^, flen);
      fileclose(fid);
      position := 0;
    end;
    procedure TBufferStream.LoadFromStream(Stm: TStream);
    var
      buf: Pointer;
      l: Integer;
    begin
      reallocmem(fbuffer, 0);
      flen := 0;
      fposition := 0;
      stm.Read(l, 4);
      if l > 0 then
      begin
        getmem(buf, l);
        stm.Read(buf^, l);
        try
          decompressbuf(buf, l, l, fbuffer, Integer(flen));
        except
          fbuffer := nil;
        end;
        freemem(buf);
      end;
    end;
    function TBufferStream.Read(var Buffer; Count: Integer): Longint;
    begin
      if fposition+count>flen then result := flen-fposition
      else result := count;
      if result > 0 then
      begin
        move(PByteArray(fbuffer)[fposition], buffer, result);
        inc(fposition, result);
      end;
    end;
    function TBufferStream.ReadString: string;
    var
      l: Integer;
    begin
      read(l, 4);
      setlength(result, l);
      if l > 0 then
        read(result[1], l);
    end;
    procedure TBufferStream.SaveToFile(FileName: string);
    var
      fid: Integer;
    begin
      fid := filecreate(filename);
      if fid < 0 then exit;
      if flen > 0 then
        filewrite(fid, fbuffer^, flen);
      fileclose(fid);
    end;
    function TBufferStream.SaveToStream(Stm: TStream): Integer;
    var
      buf: Pointer;
    begin
      try
        compressbuf(fbuffer, flen, buf, result);
      except
        result := 0;
      end;
      stm.Write(result, 4);
      if result > 0 then
      begin
        stm.Write(buf^, result);
        freemem(buf);
      end;
      inc(result, 4);
    end;
    function TBufferStream.Seek(Offset: Integer; Origin: Word): Longint;
    begin
      case origin of
        0: if offset >= 0 then fposition := offset;
        1: inc(fposition, offset);
        2: fposition := flen + offset;
      end;
      result := fposition;
    end;
    procedure TBufferStream.SetSize(NewSize: Integer);
    begin
      if flen <> newsize then
      begin
        flen := newsize;
        reallocmem(fbuffer, newsize);
        if fposition > flen then fposition := flen;
      end;
    end;
    function TBufferStream.Write(const Buffer; Count: Integer): Longint;
    begin
      try
        if fposition + count > flen then
          setsize(fposition + count);
        result := count;
        move(buffer, PByteArray(fbuffer)[fposition], count);
        inc(fposition, count);
      except
        result := 0;
      end;
    end;
    procedure TBufferStream.Writestring(const Str: string);
    var
      l: Integer;
    begin
      l := Length(str);
      write(l, 4);
      if l > 0 then
        write(str[1], l);
    end;
    { TFileRes }
    destructor TFileRes.Destroy;
    begin
      if assigned(FStream) then
        fstream.Free;
      inherited;
    end;
    procedure TFileRes.DefineProperties(Filer: TFiler);
    begin
      inherited;
      filer.DefineBinaryProperty('FileStreamData', ReadFileData, WriteFileData, assigned(fstream));
    end;
    procedure TFileRes.ReadFileData(Stm: TStream);
    begin
      if not assigned(fstream) then
        fstream := TBufferStream.Create;
      fstream.LoadFromStream(stm);
    end;
    procedure TFileRes.WriteFileData(Stm: TStream);
    begin
      if assigned(fstream) then
        fstream.SaveToStream(stm);
    end;
    function TFileRes.ResToFile(AFileName: string; Keep: Boolean): Boolean;
    var
      fid: Integer;
    begin
      result := false;
      if not assigned(fstream) then exit;
      fid := filecreate(afilename);
      if fid < 0 then exit;
      if fstream.FLen > 0 then
        filewrite(fid, fstream.fbuffer^, fstream.FLen);
      fileclose(fid);
      result := true;
      if not keep then
        freeandnil(fstream);
    end;
    function TFileRes.ResToStream(var Stm: TStream; Keep: Boolean): Boolean;
    begin
      result := assigned(fstream);
      if result then
      begin
        stm := fstream;
        if not keep then
          fstream := nil;
      end;
    end;
    procedure TFileRes.SetFileName(const Value: TFileName);
    begin
      if (csDesigning in ComponentState) {and (value <> ffilename)} then
      begin
        FFileName := Value;
        if not (csLoading in ComponentState) then
          if value <> '' then
          begin
            if not assigned(fstream) then
              fstream := TBufferStream.Create;
            fstream.LoadFromFile(value);
            if fstream.FLen = 0 then
              freeandnil(fstream);
          end
          else freeandnil(fstream);
      end;
    end;
    end. 

  • 相关阅读:
    jQuery如何获取选中单选按钮radio的值
    java计算出字符串中所有的数字求和?
    java 多线程对List中的数据进行操作
    MongoDB
    CentOS网卡一致性命名
    linux之list_for_each和list_for_each_entry函数
    linux开机启动项
    linux学习参考网站
    linux内核态获取纳秒ns时间
    Linux内核kfifo
  • 原文地址:https://www.cnblogs.com/railgunman/p/1885967.html
Copyright © 2011-2022 走看看