Autor Beitrag
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: Mo 19.01.04 19:11 
Ich kenne mich mit Streams nicht aus und fange gearade an sie zu erlernen und zu begreifen. Für ein Programm habe ich einige Prozeduren und Funktionen geschreiben und möchte gerne wissen ob sie fehlerfrei sind. Mit fehlerfrei meine ich, dass die Prozedur oder Funktion das macht was wofür sie bestimmt ist und nicht falsche Werte zurückliefert. Mit Falschen Werten ist gemeint, dass beim Arbeiten mit Streams nicht unbedingt eine Fehlermeldung zurückkommt wenn über den Stream hinweg gelesen wird. Ich möchte also wissen ob meine Prozeduren und Funktionen nach Stand der Technik fehlerfrei sind, alle Fehler abfangen und auf alle Eventualitäten vorbereitet sind.

Hier sind einge Prozeduren und Funktionen. Teile des Wissens hab ich aus einigen fremden Prozeduren und Funktionen. Den größen Teil des Quellcodes aber hab ich selbst geschreiben. Da ich das meise selbst geschrieben habe und keine große Ahnung von Streams habe, wollte ich bitten sich das anzugucken:

Bsp 1: Als ersten ein Beispiel für das Kopieren einen Streamteils. Die Datei wird in ein FileStream geladen und es wird ein Teil in ein MemoryStream kopiert.

ausblenden 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:
function StreamInSpeicherKopieren(const AFileName: String; MemoryStream:
  TMemoryStream; Index, Count: Integer): Boolean;
var
  FileStream: TFileStream;
begin
  Result := False;
  if not FileExists(AFileName) then Exit;

  FileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
  with FileStream do
  try
    if (Count < 0or
       (Index < 0or
       (Index > Size) or
       ((Index + Count) > Size) then
    begin
      Free;
      Exit;
    end;

    Seek(Index, soFromBeginning);
    MemoryStream.SetSize(Count);
    MemoryStream.CopyFrom(FileStream, Count);
    MemoryStream.Seek(0, soFromBeginning); 
  finally
    Free;
  end;
  Result := True;
end;


Bsp 2: Dann ein Beispiel für das Kopieren einen Streamteils. Hier wird die Datei in ein FileStream geladen und ein Teil von wird in eine neue Datei gespeichert.

ausblenden 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:
function StreamSpeichernInDatei(const AFromFile, AToFile: String; Index,
  Count: Integer): Boolean;
var
  FileStream1, FileStream2: TFileStream;
begin
  Result := False;
  if not FileExists(AFromFile) then Exit;

  FileStream1 := TFileStream.Create(AFromFile, fmOpenRead or fmShareDenyWrite);
  FileStream2 := TFileStream.Create(AToFile, fmCreate or fmShareDenyWrite) ;
  with FileStream1 do
  try
    if (Count < 0or
       (Index < 0or
       (Index > Size) or
       ((Index + Count) > Size) then
    begin
      FileStream2.Free;
      FileStream1.Free;
      Exit;
    end;

    Seek(Index, soFromBeginning);
    FileStream2.CopyFrom(FileStream1, Count);
  finally
    FileStream2.Free;
    FileStream1.Free;
  end;
  Result := True;
end;


Bsp 3: Hier wird ein MemoryStream an eine Datei angehängt und gespeichert. Es wird die länge des Anhangs mit abgespeichert. Zusätzlich werden noch zwei Checksummen mit gespeichert.

ausblenden 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:
function DateiAnDateiHaengenMS(const AFileName: String; MemoryStream:
  TMemoryStream): Boolean;
var
  iSize, iCheckA, iCheckB: Integer;
  FileStream: TFileStream;
begin
  Result := False;
  if not FileExists(AFileName) then Exit;

  FileStream := TFileStream.Create(AFileName, fmOpenWrite or fmShareDenyWrite);
  try
    MemoryStream.Seek(0, soFromBeginning);
    FileStream.Seek(0, soFromEnd);
    FileStream.CopyFrom(MemoryStream, 0);
    iSize := MemoryStream.Size;
    if FileStream.Write(iSize, SizeOf(iSize)) <> SizeOf(iSize) then
    begin
      FileStream.Free;
      Exit;
    end;

    iCheckA := $FFFFFFFF// Testwerte für spätere Funktion
    iCheckB := $FFFFFFFF// Testwerte für spätere Funktion
    Write(iCheckA, SizeOf(iCheckA));
    Write(iCheckB, SizeOf(iCheckB));
  finally
    FileStream.Free;
  end;
  Result := True;
end;


Bsp 4: Hier wird eine Datei an eine zweite Datei angehängt und in der zweiten gespeichert.

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:
function DateiAnDateiHaengenFS(const ADat1File, ADat2File: String): Boolean;
var
  FileStream1, FileStream2: TFileStream;
  iSize, iCheckA, iCheckB: Integer;
begin
  Result := False;
  if not FileExists(ADat1File) then Exit;
  if not FileExists(ADat2File) then Exit;

  FileStream1 := TFileStream.Create(ADat2File, fmOpenRead or fmShareDenyWrite);
  FileStream2 := TFileStream.Create(ADat1File, fmOpenWrite or fmShareDenyWrite);
  try
    FileStream1.Seek(0, soFromBeginning);
    FileStream2.Seek(0, soFromEnd);
    FileStream2.CopyFrom(FileStream1, 0);
    iSize := FileStream1.Size;
    if FileStream2.Write(iSize, SizeOf(iSize)) <> SizeOf(iSize) then
    begin
      FileStream2.Free;
      FileStream1.Free;
      Exit;
    end;

    iCheckA := $FFFFFFFF// Testwerte für spätere Funktion
    iCheckB := $FFFFFFFF// Testwerte für spätere Funktion
    FileStream2.Write(iCheckA, SizeOf(iCheckA));
    FileStream2.Write(iCheckB, SizeOf(iCheckB));
  finally
    FileStream2.Free;
    FileStream1.Free;
  end;
  Result := True;
end;


Bsp 5: Hier eine Checksummenberechnung. Die Berechnung selbst ist einfach, wird aber später verbessert. Als Quelle für die Berechnung dient ein MemorySteam, wobei hier nur der in den Parametern angegebener Teil überprüft wird.

ausblenden 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:
function ChecksumMS(MemoryStream: TMemoryStream; Index, Count: Integer): Integer;
var
  FileStream: TFileStream;
  i: Integer;
  Value: Byte;
begin
  Result := 0;

  with MemoryStream do
  begin
    if (Count < 0or 
       (Index < 0or 
       (Index > Size) or 
       ((Index + Count) > Size) then 
      Exit; 

    for i := Index to Index + Count do begin
      Seek(Index, soFromBeginning);
      Read(Value, SizeOf(Value));

      Inc(Result, Value - 65);
    end;
  end;
end;


Bsp 6: Hier eine Checksummenberechnung. Als Quelle für die Berechnung dient ein FileSteam, wobei hier nur der in den Parametern angegebener Teil überprüft wird.

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:
function ChecksumFS(const AFileName: String; Index, Count: Integer): Integer;
var
  FileStream: TFileStream;
  i: Integer;
  Value: Byte;
begin
  Result := 0;

  if not FileExists(AFileName) then Exit;

  FileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
  with FileStream do
  try
    if (Count < 0or
       (Index < 0or
       (Index > Size) or
       ((Index + Count) > Size) then
    begin
      Free;
      Exit;
    end;

    for i := Index to Index + Count do begin
      Seek(Index, soFromBeginning);
      Read(Value, SizeOf(Value));

      Inc(Result, Value - 65);
    end;
  finally
    Free
  end;
end;


Wie gesagt interresiert mich ob die Prozeduren und Funktionen Fehlerfrei sind. Das sie funktionieren weiss ich, nur weiss ich nicht ob sie immer fehlerfrei funktionieren. Hab ich irgendwelche Sicherungen vergessen?