TFileStream - Speichern und Lesen

Für Fragen von Einsteigern und Programmieranfängern...

TFileStream - Speichern und Lesen

Beitragvon RuhrPotto » 22. Feb 2017, 15:55 TFileStream - Speichern und Lesen

Hai!
Hab wohl wieder den Tag mit Brett.
Ein gleichlauten Eintrag hab ich im Forum gefunden - aber ich komm nicht weiter.

Folgende CodeStrecke funzt
Code: Alles auswählen
 
size, len : longint;
 
**** SPEICHERN ***
 
for i := 0 to Length(Daten) - 1 do begin
      Stream.Write(Daten[i].ID, SizeOf(Daten[i].ID));   // ID Speichern als Integer
      Len := Length(Daten[i].Name);
      Stream.Write(Len, SizeOf(Len));                   // Länge des Stringes speichern
      Stream.Write(Pointer(Daten[i].Name)^, Len);       // Den String selbst speichern
    end;
 
**** LADEN ****
...
for i := 0 to Len - 1 do begin
      Stream.Read(Daten[i].ID, SizeOf(Daten[i].ID));    //-- brauch ich nicht
      Stream.Read(size, SizeOf(size));
      SetLength(Daten[i].Name, size)//Teil eines Records - Ansistring
      Stream.Read(Pointer(Daten[i].Name)^, size);
end;
 
//Anmerkung size=4Byte= x'80000000'
 


Ich muß im Programm nur große Strings random lesen und verarbeiten. Daher hab ich
Code: Alles auswählen
 
 
AString : AnsiString;
size, len : longint;
 
****SPEICHERN ****
    Len := Length(AString);
    Stream.Write(Len, SizeOf(Len));                   // Länge des Stringes speichern
    Stream.Write(Pointer(AString)^, Len);             // Den String selbst speichern
 
****LADEN ****
...
   //pos := 0;
   //Stream.Seek(pos,soBeginning);  --für später
...
    Stream.Read(size, SizeOf(size));
    SetLength(AString, size);
    Stream.Read(Pointer(AString)^, size);
 
//Anmerkung auch hier size=4Byte= x'80000000'
 

nur den Stringteil verwendet.
Erstere Lösung geht, zweite nicht.

Als size lese ich immer den Wert 4 (bei der der ersten Variante 128 was mommentan OK wäre)

Jemand eine Idee?
Danke
Jeder macht Fehler - viele Fehler brauchen EDV!
RuhrPotto
 
Beiträge: 35
Registriert: 6. Mai 2015, 11:52

Beitragvon theo » 22. Feb 2017, 16:07 Re: TFileStream - Speichern und Lesen

Nimm Stream.WriteAnsiString();
theo
 
Beiträge: 7800
Registriert: 11. Sep 2006, 18:01

Beitragvon RuhrPotto » 22. Feb 2017, 16:11 Re: TFileStream - Speichern und Lesen

Stream kennt kein WriteAnsiString
Jeder macht Fehler - viele Fehler brauchen EDV!
RuhrPotto
 
Beiträge: 35
Registriert: 6. Mai 2015, 11:52

Beitragvon wp_xyz » 22. Feb 2017, 16:47 Re: TFileStream - Speichern und Lesen

RuhrPotto hat geschrieben:random lesen und verarbeiten

Wenn du mit "random lesen" meinst, dass du die Strings in beliebiger Reihenfolge haben willst, musst du wissen, bei welcher Stream-Position die Strings jeweils beginnen. Das heißt, du musst einmal den Stream von vorne bis hinten durchlaufen und dabei diese Tabelle aufbauen. Dazu reicht ein Array von Integern (oder Int64), in dem du die jeweiligen Stream-Positionen speicherst. Später, wenn du den String mit Index I lesen willst, schaust du in der Tabelle nach, an welcher Stream-Position sich der String befindet, springst an diese Position und liest den String ein so wie in deinem Code ausgeführt.
wp_xyz
 
Beiträge: 1878
Registriert: 8. Apr 2011, 08:01

Beitragvon theo » 22. Feb 2017, 17:04 Re: TFileStream - Speichern und Lesen

RuhrPotto hat geschrieben:Stream kennt kein WriteAnsiString

Aber TFileStream. Steht so in deiner Überschrift.
theo
 
Beiträge: 7800
Registriert: 11. Sep 2006, 18:01

Beitragvon Mathias » 22. Feb 2017, 17:39 Re: TFileStream - Speichern und Lesen

theo hat geschrieben:
RuhrPotto hat geschrieben:Stream kennt kein WriteAnsiString

Aber TFileStream. Steht so in deiner Überschrift.

Bei mir kennt er es auch bei TStream.

Folgendes wird bei mir anstandslos kompiliert.
Code: Alles auswählen
var
  st: TStream;
begin
.... // Create, etc.
  st.WriteAnsiString('abc');
end;
 
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 2520
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon RuhrPotto » 22. Feb 2017, 18:56 Re: TFileStream - Speichern und Lesen

Also erstmal Danke für die Antworten!

Und Upps - muss diesmal "fremdgehen" und das ganze mal wieder mit Delphi (auch noch ne aktuelle Starter) machen :(

Ich arbeite auf mehreren HOST-Entladebeständen mit fester Satzgröße (String 512 - 4096 Bytes).
Den/die Indexe muss ich selber erstellen. Ist auch kein Problem.

Ich bekomme die Daten halt nicht in einen Stream mit Random-Zugriff; selbst wenn ich den Index im Speicher habe.
Und ich hab das "Brett", warum es beim Speichern mit einem Array of Record (Beispiel: Integer- und AnsiString-Feld) klappt und bei reinen Strings nicht!?!

Das definierte Vorgehen wäre doch
- Ermitteln Stringlänge
- Speichern Stringlänge
- Speichern String (Pointer, PChar oder string[1])

Etwas anderes macht WriteAnsiString doch auch nicht:
"WriteAnsiString writes the AnsiString S (i.e. 4 bytes) to the stream. This is a utility function which simply calls the Write function. The ansistring is written as a 4 byte length specifier, followed by the ansistring's content."!
Jeder macht Fehler - viele Fehler brauchen EDV!
RuhrPotto
 
Beiträge: 35
Registriert: 6. Mai 2015, 11:52

Beitragvon Mathias » 22. Feb 2017, 19:39 Re: TFileStream - Speichern und Lesen

Code: Alles auswählen
   Stream.Write(Pointer(AString)^, Len);    

Müsste dies nicht
Code: Alles auswählen
if Len > 0 then Stream.Write(AString[1], Len);    

heisen ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 2520
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 22. Feb 2017, 19:49 Re: TFileStream - Speichern und Lesen

Ich bin 100% sicher, dass dein Problem mit den Lese/Schreibe-Routinen nichts zu tun hat, sondern mit der Erstellung des Index.

In der beigefügten Demo werden mit dem Button "Stream erzeugen" zufällige Strings erzeugt, die aber zur besseren Unterscheidung immer dieselbe Ziffer enthalten. Die Strings werden in der Listbox darunter angezeigt, wobei der Stream-Offset, bei dem jeder String beginnt, vorangestellt ist.

Mit dem Button "Index erzeugen" wird der Stream schnell eingelesen und der Index erzeugt, also die Positionen wiederum, wo ein String beginnt. Diese werden in der Listbox darunter angezeigt. Die Index-Werte stimmen exakt mit den Offsets in der linken Liste überein.

Mit dem Button "Auslesen" wird im Index der Eintrag mit dem im SpinEdit angegebenen Index ausgewählt, der Stream springt an die entsprechende Position, der String wird eingelesen und in die Listbox darunter eingetragen. Jeder angezeigte String enthält wie erwartet immer dieselben Zeichen, und die Länge stimmt auch.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
wp_xyz
 
Beiträge: 1878
Registriert: 8. Apr 2011, 08:01

Beitragvon RuhrPotto » 22. Feb 2017, 20:07 Re: TFileStream - Speichern und Lesen

Hi
und Danke @ wp_xyz für die viele Arbeit!!
Bin jetzt ausgebrannt nach 12 Stunden ... und schau es mir morgen genauer an

Ich hab noch keinen Index sondern will die Strings nur einlesen und dann im FileStream speichern.
Anschließend sequentiell lesen und Indexe erstellen.

Einlesen und anzeigen (Memo) klappt - nur speichern nicht.

Mit Testdaten sehen die Dateien aus wie im Anhang - eigentlich Ok..
.
laztestm.JPG
laztest.JPG
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Jeder macht Fehler - viele Fehler brauchen EDV!
RuhrPotto
 
Beiträge: 35
Registriert: 6. Mai 2015, 11:52

• Themenende •

Zurück zu Einsteigerfragen



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

cron
porpoises-institution
accuracy-worried