Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Datei binär einlesen (https://www.delphipraxis.net/1782-datei-binaer-einlesen.html)

nailor 23. Dez 2002 14:04


Datei binär einlesen
 
Wie kann ich von einer Datei die ersten 32 Byte (256 Bit) binär einlesen, und als Integer, Byte, String... (irgendwas womit man weiterarbeiten kann) benutzen??? Es muss egal sein, was für Werte da drin stehen, es muss immer klappen!

sakura 23. Dez 2002 14:10

Re: Datei binär einlesen
 
Zitat:

Zitat von Nailor
Es muss egal sein, was für Werte da drin stehen, es muss immer klappen!

Klappt nur, wenn auch mind. 32 Bytes vorhanden sind.

Delphi-Quellcode:
type
  TMy32Bytes = array[0..31] of Byte;
var
  My32Bytes: TMy32Bytes;
begin
  with TFileStream.Create('C:\Temp\SimpleFile.dat', fmOpenRead) do
  try
    Read(My32Bytes, SizeOf(My32Bytes));
    // jetzt kannst Du mit den 32 Bytes machen was Du willst
  finally
    Free;
  end;
  // auch hier kannst Du mit den 32 Bytes machen was Du willst
end;
So einfach.

nailor 23. Dez 2002 14:15

ok, für den speziellen fall reicht das vollkommen,
aber generell:
kann man auch die bytes einzeln einlesen, und dann immer 1 weitergehen, oder 8 oder sowas?

Christian Seehase 23. Dez 2002 14:17

Moin Nailor,

schau Dir doch einfach mal die Methode TFileStream.Read an.
Das müsste Deine Frage eigentlich beantworten.

nailor 23. Dez 2002 14:19

Ich hab die ganze DelphiHilfe nach "Read" durchsucht, aber nix gefunden, was mir zu helfen schien :(

sakura 23. Dez 2002 14:20

Re: Datei binär einlesen
 
JA.
Delphi-Quellcode:
var
  I, OneByte: TMy32Bytes;
begin
  with TFileStream.Create('C:\Temp\SimpleFile.dat', fmOpenRead) do
  try
    for I := 0 to 31 do
    begin
      Read(OneByte, SizeOf(OneByte));
      ShowMessage(IntToStr(OneByte));
    end;
  finally
    Free;
  end;
end;

Christian Seehase 23. Dez 2002 14:23

Moin Nailor,

es geht ja um die Methode Read von TFileStream, ergo:
Erst mal nach TFileStream suchen, und dann oben auf die Methoden klicken.
Dann geht ein Fenster auf mit allen Methoden, die TFileStream kennt, und Read ist dabei.

nailor 23. Dez 2002 14:24

d.h. er rückt die position in der datei automatisch nach dem lesen vor?

auf jeden fall schon mal vielen dank!!! :bouncing4: :hello:

nailor 23. Dez 2002 15:41

Noch eine Frage, bevor ich mir jede Menge Arbeit mach:

Gibt es eine andere möglichkeit, zwei Dateien zu vergleichen, ohne beide komplett Byte für Byte einzulesen und jeweils zu vergleichen?

Christian Seehase 23. Dez 2002 15:47

Moin Nailor,

wenn es Dir genügt mit einiger Wahrscheinlichkeit festzustellen, ob zwei Dateien gleich sind, könntest Du es mit einer CRC 32 Prüfsumme über beide Dateien hinbekommen.

100%ig ist das naheliegender Weise natürlich nicht, da es ja "nur" (2 hoch 32) - 1 verschiedene Prüfsummen gibt, aber wohl bestimmt mehr verschiedene Dateien.

Wenn es sicherer sein soll ginge es wohl auch mit einer MD5 Prüfsumme, wie es z.B. die Kerio Personal Firewall macht, um manipulierte/ersetzte Dateien aufzuspüren.

In keinem Falle wirst Du wohl darum herumkommen beide Dateien komplett zu lesen, nur musst Du sich nicht zwingend Byte für Byte vergleichen.

nailor 23. Dez 2002 15:56

Ok, wenn ich wissen will, ob meine Ver- Entschlüsselung geht, dann ist mir jede Checksumme zu ungenau. Also vergleich ich den Kram Byte für Byte.
...Never mind...

nailor 25. Dez 2002 23:23

Delphi-Quellcode:
//Dateivergleich
procedure TForm1.Button8Click(Sender: TObject);
var Rein, Raus: TFileStream;
    ReinKB, RausKB: array[0..1023] of byte;
    x,y,i:integer;
begin

for i := 0 to 1023 do
  begin
    ReinKB[i] := 0;
    RausKB[i] := 0;
  end;

try
  Rein := TFileStream.Create(LabeledEdit1.Text, fmOpenRead);
except
  ShowMessage('Fehler beim Öffnen der Dateien! #002a');
  Exit;
end;

try
  Raus := TFileStream.Create(LabeledEdit2.Text, fmOpenRead);
except
  Rein.Free;
  ShowMessage('Fehler beim Öffnen der Dateien! #002b');
  Exit;
end;

repeat
  begin x := Rein.Read(ReinKB, 1024);
    y := Raus.Read(RausKB, x);
    if x <> y then
      begin
        ShowMessage('Unterschiedlich - Dateivergleich negativ, Dateilängen falsch! #003');
        Rein.Free;
        Raus.Free;
        Exit;
      end;
    for i := 0 to 1023 do
      if ReinKB[i] <> RausKB[i] then
        begin
          ShowMessage('Unterschiedlich - Dateivergleich negativ, Abweichung festgestellt! #004');
          Rein.Free;
          Raus.Free;
          Exit;
        end;
  end;
until x = 0;

ShowMessage('Gleich - Dateivergleich postiv');
Rein.Free;
Raus.Free;
end;
Wenn der jetzt an #002a oder #002b rausspringt, kann das andere Gründe haben, als dass die Datei von einem anderen Programm geöffnet ist? Also zu groß... oder so was

nailor 26. Dez 2002 00:23

Mir ist grade was aufgefallen an dem Code. Wenn die zweite Datei länger ist als die erste, können die immer noch als gleich getestet werden. Wird behoben. Aber meine eigentliche Frage bleibt. :coder:

Christian Seehase 27. Dez 2002 03:28

Moin Nailor,

wenn Du vor der Prüfschleife einfach rein.size und raus.size vergleichst, und dann zu dem Ergebnis kommst, dass die Werte ungleich sind, können die Dateien schon mal nicht gleich sein.
Dazu musst Du nicht erste eine der beiden durchlesen.

Ausserdem fehlt noch der try/finally Block der garantiert, dass die belegten Resourcen wieder freigegeben werden.

Wenn Du die beiden Buffer nicht als array of Byte sondern schlicht als Strings deklarierst, und jeweils auf 1024 würdest Du Dir auch die zweite Schleife einsparen können. Für den letzten Vergleich (es werden weniger als 1024 Zeichen gelesen) müsste dann allerdings verkürzt verglichen werden, also z.B. mit Copy(sRaus,1,ReadByte) <> Copy(sRein,1,ReadByte).

Was mir jetzt noch fehlt:
Welche eigentliche Frage meinst Du?

nailor 28. Dez 2002 17:36

Wenn der jetzt an #002a oder #002b rausspringt, kann das andere Gründe haben, als dass die Datei von einem anderen Programm geöffnet ist? Also zu groß... oder so was

----

zb. ram...

Christian Seehase 29. Dez 2002 04:15

Moin Nailor,

das dürfte an den genannten Stellen eigentlich nur passieren, wenn die Datei schon anderweitig geöffnet ist, oder nicht existiert.

Probier doch mal statt Deines ShowMessage folgende Variante:

Delphi-Quellcode:
ShowMessage(SysErrorMessage(GetLastError));
Dann sollte Dir die passende Windowsfehlermeldung präsentiert werden.
Da TFileStream intern auf der API CreateFile basiert sollte das eine sinnvolle Meldung bringen.

Oder aber, Du schreibst einfach in den except Abschnitt, unmittelbar vor das exit noch eine Zeile in der raise; steht. Dann wird die zuletzt ausgelöste Exception noch einmal ausgelöst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz