var
  filename:string;
  bt:TBytes;
begin
filename:='丰碑';
SetLength(bt,12); //'丰碑'压缩后的TBytes
bt[0]:=120;
bt[1]:=1;
bt[2]:=51;
bt[3]:=240;
bt[4]:=155;
bt[5]:=88;
bt[6]:=1;
bt[7]:=0;
bt[8]:=3;
bt[9]:=72;
bt[10]:=1;
bt[11]:=136;
//bt:=ZCompressStr(filename, zcFastest); //压缩
ShowMessage(ZDecompressStr(bt)); //解压
end;这里都是能够正常压缩和解压的
但是我真正需要用的一些TBytes,是已经压缩过的,需要直接解压,一使用ZDecompressStr函数就报错:data error
数据损坏或者数据不完整!
这个要怎么办??

解决方案 »

  1.   


    bt:=ZCompressStr(filename, zcFastest); //压缩
    这个返回出来的bt就是12个字节的
      

  2.   

    unit uZlibHelper;interface
    uses
      zlib, Classes;procedure PackStream(const Src:TStream; Dst:TStream; CompressionLevel: TCompressionLevel = clFastest); inline;
    function ZlibPackString(const SrcString: AnsiString; CompressionLevel: TCompressionLevel = clFastest): AnsiString; inline;
    function ZlibPackBuffer(const SrcData: PAnsiChar; SrcDataLen: LongWord; CompressionLevel: TCompressionLevel = clFastest): AnsiString; inline;
    procedure UnpackStream(const Src:TStream; Dst:TStream); inline;
    function ZlibUnpackString(const SrcString: AnsiString): AnsiString; inline;
    implementation
    //将Src使用Zlib压缩后存入Dst当中
    procedure PackStream(const Src:TStream; Dst:TStream; CompressionLevel: TCompressionLevel); inline;
    var
      CompStream: TCompressionStream;
    begin
      //增加“断言”以防止输入参数有误
      Assert(Src <> Nil);
      Assert(Dst <> Nil);  CompStream := TCompressionStream.Create(CompressionLevel,Dst);
      try
        //将源数据的偏移转到首部
        Src.Seek(0,soFromBeginning);
        //使用CopyFrom将源数据输入到压缩流,以实现压缩
        CompStream.CopyFrom(Src,0);
      finally
        CompStream.Free;
      end;
    end;function ZlibPackString(const SrcString: AnsiString; CompressionLevel: TCompressionLevel): AnsiString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(SrcString[1], Length(SrcString));
          PackStream(Src, Dst, CompressionLevel);
          SetString(Result, PAnsiChar(Dst.Memory), Dst.Size);
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;function ZlibPackBuffer(const SrcData: PAnsiChar; SrcDataLen: LongWord; CompressionLevel: TCompressionLevel): AnsiString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(SrcData^, SrcDataLen);
          PackStream(Src, Dst, CompressionLevel);
          SetString(Result, PAnsiChar(Dst.Memory), Dst.Size);
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;//将以zlib压缩的Src解压缩后存入Dst当中 
    procedure UnpackStream(const Src:TStream; Dst:TStream); inline;
    var
      DecompStream: TDecompressionStream;
      NewSize: Int64;var
      N: Longint;
      Buffer: array[0..4095] of Byte;
    begin
      //增加“断言”以防止输入参数有误
      Assert(Src <> Nil);
      Assert(Dst <> Nil);  DecompStream := TDecompressionStream.Create(Src);
      try
        //NewSize := Src.Size;
        //将源数据的偏移转到首部
        NewSize := 0;
        Dst.Seek(0, soFromBeginning);
        DecompStream.Seek(0,soFromBeginning);
        repeat
          N := DecompStream.Read(Buffer[0],4096);
          Dst.WriteBuffer(Buffer,N);
          NewSize := NewSize + N;
        until N <> 4096;
      finally
        DecompStream.Free;
      end;
    end;function ZlibUnpackString(const SrcString: AnsiString): AnsiString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(SrcString[1], Length(SrcString));
          UnpackStream(Src, Dst);
          SetString(Result, PAnsiChar(Dst.Memory), Dst.Size);
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;
    end.
      

  3.   

    加入Unicode支持
    unit uZlibHelper;interface
    uses
      zlib125, Classes;procedure PackStream(const Src:TStream; Dst:TStream; CompressionLevel: TCompressionLevel = clFastest); inline;
    function ZlibPackString(const SrcString: AnsiString; CompressionLevel: TCompressionLevel = clFastest): AnsiString; overload; inline;
    function ZlibPackString(const SrcString: WideString; CompressionLevel: TCompressionLevel = clFastest): WideString; overload; inline;
    function ZlibPackBuffer(const SrcData: PAnsiChar; SrcDataLen: LongWord; CompressionLevel: TCompressionLevel = clFastest): AnsiString; inline;
    procedure UnpackStream(const Src:TStream; Dst:TStream); inline;
    function ZlibUnpackString(const SrcString: AnsiString): AnsiString; overload; inline;
    function ZlibUnpackString(const SrcString: WideString): WideString; overload; inline;
    implementation
    //将Src使用Zlib压缩后存入Dst当中
    procedure PackStream(const Src:TStream; Dst:TStream; CompressionLevel: TCompressionLevel); inline;
    var
      CompStream: TCompressionStream;
    begin
      //增加“断言”以防止输入参数有误
      Assert(Src <> Nil);
      Assert(Dst <> Nil);  CompStream := TCompressionStream.Create(CompressionLevel,Dst);
      try
        //将源数据的偏移转到首部
        Src.Seek(0,soFromBeginning);
        //使用CopyFrom将源数据输入到压缩流,以实现压缩
        CompStream.CopyFrom(Src,0);
      finally
        CompStream.Free;
      end;
    end;function ZlibPackString(const SrcString: AnsiString; CompressionLevel: TCompressionLevel): AnsiString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(SrcString[1], Length(SrcString));
          PackStream(Src, Dst, CompressionLevel);
          SetString(Result, PAnsiChar(Dst.Memory), Dst.Size);
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;function ZlibPackString(const SrcString: WideString; CompressionLevel: TCompressionLevel): WideString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(Pointer(SrcString)^, Length(SrcString)* sizeof(WideChar));
          PackStream(Src, Dst, CompressionLevel);
          SetString(Result, PWideChar(Dst.Memory), (Dst.Size + sizeof(WideChar) - 1) div Sizeof(WideChar));
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;function ZlibPackBuffer(const SrcData: PAnsiChar; SrcDataLen: LongWord; CompressionLevel: TCompressionLevel): AnsiString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(SrcData^, SrcDataLen);
          PackStream(Src, Dst, CompressionLevel);
          SetString(Result, PAnsiChar(Dst.Memory), Dst.Size);
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;//将以zlib压缩的Src解压缩后存入Dst当中 
    procedure UnpackStream(const Src:TStream; Dst:TStream); inline;
    var
      DecompStream: TDecompressionStream;
      NewSize: Int64;var
      N: Longint;
      Buffer: array[0..4095] of Byte;
    begin
      //增加“断言”以防止输入参数有误
      Assert(Src <> Nil);
      Assert(Dst <> Nil);  DecompStream := TDecompressionStream.Create(Src);
      try
        //NewSize := Src.Size;
        //将源数据的偏移转到首部
        NewSize := 0;
        Dst.Seek(0, soFromBeginning);
        DecompStream.Seek(0,soFromBeginning);
        repeat
          N := DecompStream.Read(Buffer[0],4096);
          Dst.WriteBuffer(Buffer,N);
          NewSize := NewSize + N;
        until N <> 4096;
      finally
        DecompStream.Free;
      end;
    end;function ZlibUnpackString(const SrcString: AnsiString): AnsiString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(SrcString[1], Length(SrcString));
          UnpackStream(Src, Dst);
          SetString(Result, PAnsiChar(Dst.Memory), Dst.Size);
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;function ZlibUnpackString(const SrcString: WideString): WideString; inline;
    var
      Src:TMemoryStream;
      Dst:TMemoryStream;
    begin  Src:=TMemoryStream.Create;
      try
        Dst:=TMemoryStream.Create;
        try
          Src.WriteBuffer(Pointer(SrcString)^, Length(SrcString)*sizeof(WideChar));
          UnpackStream(Src, Dst);
          SetString(Result, PWideChar(Dst.Memory), (Dst.Size + sizeof(WideChar) - 1) div sizeof(WideChar));
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;
    end.
      

  4.   

    对于Unicode支持的时候有可能会因为被解压的源压缩数据比实际的多(实际压缩后得到的是单数字节数),此时就需要对Zlib.pas单元解压过程进行调整
    function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
    var
      current,remain: LongInt;
    begin
      FZRec.next_out := @Buffer;
      FZRec.avail_out := Count;
      if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
      remain := 0;
      while (FZRec.avail_out > 0) do
      begin
        current := FZRec.avail_in;
        if FZRec.avail_in = remain then
        begin
          FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
          if FZRec.avail_in = remain then
          begin
            Result := Count - FZRec.avail_out;
            Exit;
          end;
          FZRec.next_in := FBuffer;
          FStrmPos := FStrm.Position;
          Progress(Self);
        end;
        CCheck(inflate(FZRec, 0));    if current = FZRec.avail_in then remain := current;
      end;
      Result := Count;
    end;
      

  5.   

    unsigned 
    (僵哥(自然界因不公平生生不息)) 
    太感动了,谢谢分享,我整理学习中
      

  6.   

    其实里面有一个BUG。
    自己找吧