Entwickler-Ecke

Dateizugriff - stream komprimieren...


knightkiller - Fr 19.07.02 10:56
Titel: stream komprimieren...
Habe eine Funktion geschrieben, mit der man Streams de/komprimieren kann. Leider ist hier irgendwo ein Fehler. Es Kommt manchmal (meistens bei grösseren Streams) bei De/CompressBuf eine Exception...

Vielleicht findet einer Von Euch den Fehler:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
procedure CompOrUncomp(var Stream : TMemoryStream; Komp : Boolean);
var myStream : TMemorystream;

  procedure DecompressStream(inpStream, outStream: TStream);
  var
    InpBuf, OutBuf: Pointer;
    OutBytes, sz: Integer;
  begin
    InpBuf := nil;
    OutBuf := nil;
    sz     := inpStream.Size - inpStream.Position;
    if sz > 0 then
      try
        GetMem(InpBuf, sz);
        inpStream.Read(InpBuf^, sz);
        DecompressBuf(InpBuf, sz, 0, OutBuf, OutBytes); //Fehler ?!
        outStream.Write(OutBuf^, OutBytes);
      finally
        if InpBuf <> nil then FreeMem(InpBuf);
        if OutBuf <> nil then FreeMem(OutBuf);
      end;
    outStream.Position := 0;
  end;

  procedure CompressStream(inpStream, outStream: TStream);
  var
    InpBuf, OutBuf: Pointer;
    InpBytes, OutBytes: Integer;
  begin
    InpBuf := nil;
    OutBuf := nil;
    try
      GetMem(InpBuf, inpStream.Size);
      inpStream.Position := 0;
      InpBytes := inpStream.Read(InpBuf^, inpStream.Size);
      CompressBuf(InpBuf, InpBytes, OutBuf, OutBytes); //Fehler ?!
      outStream.Write(OutBuf^, OutBytes);
    finally
      if InpBuf <> nil then FreeMem(InpBuf);
      if OutBuf <> nil then FreeMem(OutBuf);
    end;
  end;

begin
  myStream := TMemorystream.create;
  if Komp then
    CompressStream(Stream,myStream)
  else
    DeCompressStream(Stream,myStream);
  Stream.Size := myStream.Size;
  Stream.LoadFromStream(myStream);
  Stream.Position := 0;
  FreeAndNil(mystream);
end;


knightkiller - Fr 19.07.02 11:08

also das mit der Exception ist gelöst... habe das Kreieren (in meiner Source, oben stimmts) von myStream vergessen.

ABER, nach dem dekomprimieren ist der Stream 0 Bytes gross!
(komischerweise funktionierts beim Komprimieren)


knightkiller - Mo 29.07.02 11:18

Kann mir BITTE jemand helfen?! *anfleh*

Wieso ist beim dekomprimieren des Streams, der Stream immer 0 Bytes gross? (source siehe oben):?: :?: :?:


hitstec - Mo 29.07.02 14:57

Vielleicht fehlt ein


Quelltext
1:
inpStream.Position:=0;                    

nach


Quelltext
1:
OutBuf := nil;                    


in DecompressStream().

Wenn es nicht hilft, dann schau dir folgende Prozeduren an, die funken:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
function CompressStream(inpStream: TMemoryStream): TMemoryStream;
var 
  InpBuf, OutBuf: Pointer; 
  InpBytes, OutBytes: Integer; 
  outStream: TMemoryStream;
begin
  InpBuf := nil; 
  OutBuf := nil; 
  outStream:=TMemoryStream.Create;
  try
    GetMem(InpBuf, inpStream.Size); 
    inpStream.Position := 0; 
    InpBytes := inpStream.Read(InpBuf^, inpStream.Size); 
    CompressBuf(InpBuf, InpBytes, OutBuf, OutBytes);
    outStream.Write(OutBuf^, OutBytes);
  finally 
    if InpBuf <> nil then FreeMem(InpBuf); 
    if OutBuf <> nil then FreeMem(OutBuf); 
  end;
  result:=outStream;
end;

function DecompressStream(inpStream: TMemoryStream): TMemoryStream;
var
  InpBuf, OutBuf: Pointer;
  OutBytes, sz: Integer;
  outStream: TMemoryStream;
begin
  InpBuf := nil;
  OutBuf := nil;
  outStream:=TMemoryStream.Create;
  inpStream.Position:=0;
  sz     := inpStream.Size - inpStream.Position;
  if sz > 0 then
    try
      GetMem(InpBuf, sz);
      inpStream.Read(InpBuf^, sz);
      DecompressBuf(InpBuf, sz, 0, OutBuf, OutBytes);
      outStream.Write(OutBuf^, OutBytes);
    finally
      if InpBuf <> nil then FreeMem(InpBuf);
      if OutBuf <> nil then FreeMem(OutBuf);
    end;
  outStream.Position := 0;
  Result:=outStream;
end;


knightkiller - Mo 29.07.02 15:26

Funktioniert auch nicht. jetzt bekomme ich die Exception: Invalid Pointer Operation

Meine Funktion beinhaltet ja diese beiden. Ich will nur eine Funktion, der man EINEN Stream übergeben kann, der dann komprimiert oder dekomprimiert wird und nicht ein InPut Stream und einen OutPut Stream.

Eigetlich sollte das nicht so schwer sein :? oder :?:


hitstec - Mo 29.07.02 15:43

Ich habe jetzt deinen Code selbst ausprobiert. Der generiert nur dann einen Fehler, wenn du versuchts einen nicht komprimierten Stream zu dekomprimieren. Das ist auch verständlich das Zlib da meckert.

Ansonsten funktioniert der Code tadellos auch mit größeren Streams > 3 MB.


knightkiller - Mo 29.07.02 15:52

habe einen Feher gefunden! und es ist nicht mal meiner!
Ich habe eine Komponenten-libary (Internet-Professional von TurboPower) installiert und diese hat die zlib libary ersetzt! Offenbar haben die einen Feher geproggt.... Habe die Files umbenannt und jetzt gibt es kein Fehler mehr.

Aber dafür ist die Komprimierte und danach Dekomprimierte Datei zur Sau...
wahrscheinlich ist es diesmal mein Fehler :oops:
Vielen Dank für Deine Hilfe


hitstec - Mo 29.07.02 16:24

Zitat:
habe einen Feher gefunden!

Freut mich. :P