Autor Beitrag
hRb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 187
Erhaltene Danke: 11



BeitragVerfasst: Do 26.03.20 18:15 
Hallo zusammen,
die Frage zum "Optimalen" Lesen beliebiger Dateien blieb 12 Tage ohne Antwort. Ich zergliedere meine Frage neu, weil ich beim Realisieren meiner Aufgabe auf zwei Syntax-Probleme gestoßen bin, bei der ich Hilfe benötige. Aufgabe lautet nach wie vor: Einlesen einer beliebigen Datei ins Memory und Daten in Hexaform darstellen. Lade hierzu die Datei in einen MemoryStream. Habe dazu folgende Funktion geschrieben, die mich jedoch in mehreren Punkten nicht befriedigt:
1. Kann FiStream nicht mit der Option fmOpenRead or fmShareDenyNone einlesen. Dies führt bei schon geöffneter Datei zu error.
2. MemoryStream ist ein Pointer. Ich dachte hiermit auf die Daten direkt zugreifen zu können. Habe Syntax-Problem mit Pointer! (Über die Read-Funktion mit einem weiteren Buffer funktioniert mein Programm. (wäre aber ein weiteres Umspeichern der Daten). Wie greife ich auf die Daten von MemoryStrem direkt zu?
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:
Function ReadFi(FileName:string):boolean;
var
  Buffer: TBytes;
  FiStream : TMemoryStream;
  j: int64;
  s: string;
begin
  try
    s:='';
//   FiStream:=TMemoryStream.Create(FileName, fmOpenRead or fmShareDenyNone); //funktioniert nicht, daher der Umweg über Zeile 11+12
    FiStream := TMemoryStream.Create;
    FiStream.LoadFromFile(FileName); // Load stream, Funktion erlaubt jedoch nicht  fmOpenRead or fmShareDenyNone
    FiStream.Position := 0;          // Reset to stream-start.
//    for j:=1 to 50 {FiStream.Size} do
//      s:= s + IntToHex(ord(FiStream.Memory^.[j]),2) + ' ';  //Syntax-Fehler: Memory^.[j] wie richtig?
    SetLength(Buffer, FiStream.Size);
    FiStream.ReadBuffer(Pointer(Buffer)^, FiStream.Size);
    for j:=0 to 50 {FiStream.Size} do
//Bearbeitung wurde hier auf 50 Zeichen zum Test verkürzt, später Hexa-Zeilen 
      s:= s + IntToHex(ord(Buffer[j]),2) + ' ';
      Form1.RichEdit1.Lines.Add(s);
  except
    on Exception do begin
      FiStream.Free;
      Result:=False;
      exit;
    end;
  end;
  FiStream.Free;
  Result:=true;
end;
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4154
Erhaltene Danke: 865

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Do 26.03.20 19:08 
Warum benutzt du hier überhaupt einen TMemoryStream und nicht gleich einen TFileStream?
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8455
Erhaltene Danke: 444

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.2 CE
BeitragVerfasst: Do 26.03.20 19:46 
Grade bei sehr, sehr großen Daten wird der Ansatz mit MemoryStream nicht mehr funktionieren, denke ich. Soweit ich weiß, lädt LoadFromFile die gesamte Datei in den Speicher - und bei 32-Bit-Anwendungen ist dann in der Regel irgendwo zwischen 1 und 2GB Schluss.

Daher: Mit FilesStream arbeiten, die Daten häppchenweise in den Buffer laden, verarbeiten, und dann den nächsten Teil laden.

Aber zu deiner Frage direkt: Das sollte so gehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var ms: TMemoryStream;
  p: ^Byte;
  b: Byte;
  i: Integer;
// ...
p := ms.Memory;
for i := 0 to 100 do
begin
  b := p^;
  Memo1.Lines.Add(IntToStr(b));
  inc(p);
end;

_________________
Oel ngati kameie.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 187
Erhaltene Danke: 11



BeitragVerfasst: Do 26.03.20 21:44 
Zunächst Danke,
damit der Hintergrund meiner Frage besser erkennbar wird: Ich habe eine ganze Reihe von Speichersticks und Festplatten mit Sicherungskopien von Dateien, genauer gesagt auch ganze Ordner. Hier gibt es Textdateien aber auch andere Typen. Diese möchte ich auf Byteebene zu vergleichen. Einmal komplette Ordner, aber auch gezielt zwei Einzeldateien. Ein Vergleichsprogramm das auf Filename, Datum und Dateilänge vergleicht habe ich schon. Eigenartigerweise finde ich jedoch auch namensgleiche Dateien, die genau eine Stunde Differenzzeit aufweisen. Nun wollte ich mir ein eigenes Vergleichsprogramm schaffen. Gedacht war schon, dass ich immer Teilblöcke von 4096 Byte vergleiche und die Anzeige erst beim beim ersten Unterschied aktiviere.
Ich habe ein solches Programm mit Delphi 7 schon (mit einer schrecklichen Oberfläche). Ist auch viel zu langsam und knallt bei großen Dateien (war eines meiner Erstlingswerke, ohne try).

Werde nun, Eurem Rat folgend, mir TFilestream einmal genauer ansehen, wie dies gehen könnte. Oder kennt jemand einen Link auf ein Beispiel bei dem man spicken kann? Die Embarcadero-Hilfe zeigt zwar die Methoden, aber mir fehlen als Ungeübter die Beispiele.
Gruß hRb
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10134
Erhaltene Danke: 1231

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 27.03.20 01:27 
Moin!

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Eigenartigerweise finde ich jedoch auch namensgleiche Dateien, die genau eine Stunde Differenzzeit aufweisen.
So eigenartig ist das gar nicht. ;) Das tritt auf oder kann auftreten, wenn man Sommerzeitunterschiede in zwei verschiedenen Dateisystemen (typisch: NTFS und FAT) hat. Die Differenz ist nur virtuell und auf die Art der Datumsspeicherung in den Dateisystemen zurückzuführen. :idea:

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Nun wollte ich mir ein eigenes Vergleichsprogramm schaffen.
Deinen Schaffensdrang in allen Ehren: wenn du einfach nur das Problem lösen willst (welches ausser dir noch ca. 3 Millionen Computernutzer weltweit sicher auch schon hatten :lol:), dann nimm doch einfach eines der bereits existierenden Tools, wie den FreeFileSync. :nixweiss: Das funktioniert bereits (und auch noch schnell), so dass du die Zeit in die Lösung des eigentlichen Problems investieren könntest. :angel:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4154
Erhaltene Danke: 865

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Fr 27.03.20 08:46 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Eigenartigerweise finde ich jedoch auch namensgleiche Dateien, die genau eine Stunde Differenzzeit aufweisen. Nun wollte ich mir ein eigenes Vergleichsprogramm schaffen.

Kennst du schon FreeFileSync (welches auch Zeitdifferenzen, welche meistens aufgrund von Sommer-/Winterzeit entstehen, beachtet)?

Edit: Ups, jetzt erst den letzten Beitrag von Narses gelesen ("2 Dumme, 1 Gedanke" - soll aber KEINE Beleidigung sein ;- ).