Autor Beitrag
HawkLUED
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62

WinXP
Delphi 7 Enterprise, Delphi 2007
BeitragVerfasst: Do 14.12.06 09:52 
Hi zusammen,

ich bastele gerade an einer DLL, welche zwei Funktionen exportiert. Die erste komrimiert alle Dateien unterhalb eines angegebenen Verzeichnisses, und die andere entpackt diese Dateien wieder an einer gewünschten Position.

Das klappt alles soweit wunderbar. Einziges Problem taucht auf, wenn Dateien der Größe 0 vorkommen. Das hinzufügen, also das Komprimieren ist kein Problem, aber beim Dekomprimieren bekomme ich Fehlermeldungen:

Hinweis: Ich benitze die zlibex Unit in der Version 1.1.4.

Fehler taucht bei dem Aufruf "outfile.CopyFrom(decompr,l)" auf --> Fehlermeldung "data error"

Weiss jmd. Rat, wie man Dateien der Größe 0 behandeln muss???

Vielen Dank im voraus!

Gruß

Hawk

ausblenden volle Höhe Delphi-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:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
function CompressFiles(RootFolder : PChar; const Archivname : PCHar): integer; stdcall;
var
  infile, outfile, tmpFile : TFileStream;
  compr : TZCompressionStream;
  i,l,l1: Integer;
  s : String;
  Files: TStringList;

begin
  try {except}
    Files := TStringList.Create;
    try {finally}
      FindAllFiles(Files, RootFolder);

      if Files.Count > 0 then
      begin
        outFile := TFileStream.Create(Archivname,fmCreate);
        try
          { the number of files }
          l := Files.Count;
          outfile.Write(l,SizeOf(l));
          for i := 0 to Files.Count-1 do
          begin
            infile := TFileStream.Create(RootFolder + Files[i],fmOpenRead);
            try
              { the original filesize }
              l := infile.Size;
              { the original filename }
              s := Files[i];
              l1 := Length(s);
              outfile.Write(l1,SizeOf(l1));
              outfile.Write(s[1],l1);
              outfile.Write(l,SizeOf(l));
              { compress and store the file temporary}
              tmpFile := TFileStream.Create('tmp',fmCreate);
              compr := TZCompressionStream.Create(tmpfile, zcMax);
              try
                compr.CopyFrom(infile,l);
              finally
                compr.Free;
                tmpFile.Free;
              end;
              
              tmpFile := TFileStream.Create('tmp',fmOpenRead);
              try
                outfile.CopyFrom(tmpFile,0);
              finally
                tmpFile.Free;
              end;
            finally
              infile.Free;
            end;
          end;
        finally
          outfile.Free;
        end;
        DeleteFile('tmp');
      end;
    finally
      Files.Free;
    end;

    Result := 0;
  except
    Result := 1;
  end;
end;

function DecompressFile(const Filename, DestDirectory : PChar):integer; stdcall;
var
  dest,s, dir : String;
  decompr : TZDecompressionStream;
  infile, outfile : TFilestream;
  i,l,c : Integer;

begin
  try {except}    
    dest := IncludeTrailingPathDelimiter(DestDirectory);

    infile := TFileStream.Create(Filename,fmOpenRead);
    try
      { number of files }
      infile.Read(c,SizeOf(c));
      for i := 1 to c do
      begin
        { read filename }
        infile.Read(l,SizeOf(l));
        SetLength(s,l);
        infile.Read(s[1],l);
        { read filesize }
        infile.Read(l,SizeOf(l));
        { decompress the files and store it }
        s := dest+s; //include the path
        s := StringReplace(s, '\\', '\',[rfReplaceAll]);
        dir := ExtractFilePath(s);
        ForceDirectories(dir);
        outfile := TFileStream.Create(s,fmCreate);
        decompr := TZDecompressionStream.Create(infile);
        try
          outfile.CopyFrom(decompr,l);
        finally
          outfile.Free;
          decompr.Free;
        end;
      end;
    finally
      infile.Free;
    end;

    Result := 0;
  except
    Result := 1;
  end;
end;

_________________
Wenn Debuggen der Vorgang ist, Fehler aus einem Programm auszubauen,
dann ist Programmieren der Vorgang, Fehler in ein Programm einzubauen !
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Do 14.12.06 12:52 
Hallo,

die Lösung ist so einfach, dass du eigentlich auch selber hättest draufkommen können. Der Fehler liegt in Zeile 100:
ausblenden Delphi-Quelltext
1:
outfile.CopyFrom(decompr,l);					

Für l=0 hat CopyFrom eine spezielle Aufgabe, siehe Hilfe zu CopyFrom. Deshalb musst du überprüfen ob l>0 ist und nur dann dekomprimieren!

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
HawkLUED Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62

WinXP
Delphi 7 Enterprise, Delphi 2007
BeitragVerfasst: Do 14.12.06 19:09 
Titel: Hi!
Hi,

danke für Deine Antwort!

Das hatte ich mir auch schon gedacht und eben mal ausprobiert, das klappt aber nicht!

JA, es wird die Datei angelegt mit 0 Bytes
NEIN, ab dann gibt es Probleme beim Auslesen des Streams. z.B. liest den Dateinamen nicht als "XY.txt", sondern er hat dann "XY.txt#38#00## usw."

Bin ratlos!

Gruß

hawk

_________________
Wenn Debuggen der Vorgang ist, Fehler aus einem Programm auszubauen,
dann ist Programmieren der Vorgang, Fehler in ein Programm einzubauen !
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Mo 18.12.06 13:31 
Hallo,

ich würde alles nach Zeile 87 in eine If-Abfrage packen und nur dann ausführen, wenn l größer null ist. Zusätzlich das ganze nur mit einer Null-Byte-Datei überprüfen und das Programm auch beim packen im Einzelschritt durchgehen um zu sehen ob das packen richtig funktioniert.
So sollte der Fehler eigentlich zu finden sein...

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.