AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Nutzung MemoryStream und FileStream

Ein Thema von BasilBavaria · begonnen am 18. Mai 2011 · letzter Beitrag vom 19. Mai 2011
Antwort Antwort
Seite 1 von 3  1 23      
BasilBavaria

Registriert seit: 18. Mai 2011
Ort: Niederbayern
22 Beiträge
 
Turbo Delphi für Win32
 
#1

Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 10:25
Hai!

Ne Frage, ob ich ein grundsätzliches Denkproblem habe:

Im Prog werden Formulardaten mittels TWriter in einen MemoryStream geschrieben. Alle String-Felder werden ggfs. auf eine fixe Länge
gebracht.
Somit entsteht am Ende eine feste Struktur (Memorystream.Size = 4933).

Diese wird dann in einem Filestream gespeichert. Bei 10 Einträgen stehen also 10 Datenstrukturen im Filestream.

Vor dem Einfügen wird Pos auf (0,soFromEnd) gesetzt.
Beim Update erolgt das positionieren mittels Seek(SNr * Size,soFromBeginning).
Dem Grunde nach erfolgt also die Abbildung einer typisierten Datei.

Aus irgendeinem Grund funktioniert das ne ganze Zeit ganz gut und dann ist der Stream auf einmal zerschossen.
Beim Lesen erfolgt die Meldung "ungültiger Typ" - das Lesen erfolgt analog dem Schreiben bezogen aus Positionierung, dann werden die Teile mittels TReader gelesen.

Ist diese Vorgehensweise grundsätzlich daneben?
Kann sich die Size des Streams trotz fester Feldlängen ändern? (Dies würde das ganze erklären).

Bin für jeden Vorschlag offen.
Danke und viele Grüße
Der Basil
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 10:27
Hallo,

Also erstmal würde ich direkt in den Filestream schreiben. Der Umweg über den Memorystream ist eigentlich nicht nötig!

Also wenn du mit einem leeren Stream anfängst und dann nach und nach alle Daten reinschreibst, dann brauchst du eigentlich nicht zu seeken...

Es wäre eventuell nützlich wenn du etwas Code posten könntest

Gruß
Neutral General
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.080 Beiträge
 
Delphi 12 Athens
 
#3

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 10:32
Du kannst auch .Position := 4933 * x; setzen,
aber wenn du der Reihe nach Speicherst und ausliest, brauchst du dieses nicht setzen.
Die relative Position zum Dateiende stimmt ja nur, wenn die Dateigröße korrekt ist.


Kann sich die Size des Streams trotz fester Feldlängen ändern? (Dies würde das ganze erklären).
Nein, es sei denn du machst was falscht ... z.B. unterschiedliche Größen des Memory-Streams.

Ich würde an deiner Stelle vor dem Speichern die Größe des MemoryStreams prüfen
Delphi-Quellcode:
is MS.Size <> 4933 then
  Fehlermeldung;
Und vor dem Auslesen, bzw. vor/nach dem Speichern die Dateigröße, sowie die aktuelle Position.
Delphi-Quellcode:
if (FS.Size mod 4933 <> 0) or (FS.Position mod 4933 <> 0) then
  Fehlermeldung;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
BasilBavaria

Registriert seit: 18. Mai 2011
Ort: Niederbayern
22 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 10:39
Also - der FileStream wird nur einmal angelegt und liegt als Datendatei vor (Lesen und Schreiben). Daher das Positionieren.
Er wird also quasi wie ne Datenbank genutzt.
Je nach nach Zugriff werden 0-n Sätze gelesen via Index und müssen dann bei Änderung upgedatet werden. Auch dafür ist die Positionierung nötig (und der Vergleich mit der typisierten Datei).
Der ganze FileStream kann am Ende mehrere 100 Ds umfassen - die sollen nicht alle im Speicher stehen.

Die Prüfroutinen zur Stream.Size sind nicht überall drin. Werd ich mal ergänzen.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 10:41
Ohne den Thread jetzt hier sprengen zu wollen, aber wäre es nicht sinnvoller über die Verwendung einer kleine Datenbank nachzudenken?
(z.B. SQLite, Firebird embedded)
Dann hast du mit dem ganzen Stream-Gedöns nix mehr am Hut
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 11:36
Aus irgendeinem Grund funktioniert das ne ganze Zeit ganz gut und dann ist der Stream auf einmal zerschossen.
Beim Lesen erfolgt die Meldung "ungültiger Typ" - das Lesen erfolgt analog dem Schreiben bezogen aus Positionierung, dann werden die Teile mittels TReader gelesen.
Was ist "eine ganze Zeit lang"?

Im Prinzip liest sich das ganz richtig (nur das seek(0,sofromEnd) für das Einfügen? eher Anhängen)
(ich würde übrigens enen Puffer füllen und dann schreiben ohne diese Memory-Teil)

Wo erfolgt die Fehlermeldung?
Wie wäre es mit ein wenig Code?

Gruß
K-H

@Sir Rufo
für 20Kb gleich einen Feuervogel anschleppen?
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#7

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 11:48
Somit entsteht am Ende eine feste Struktur (Memorystream.Size = 4933).
Diese wird dann in einem Filestream gespeichert. Bei 10 Einträgen stehen also 10 Datenstrukturen im Filestream
Sehr gefährlich darauf zu vertrauen, dass es immer 4933 Bytes sind.
Irgendwo ein Byte mehr oder weniger (und das ist eigentlich bei TReader/TWriter zwangsläufig so) und die gesamten Daten sind unlesbar.
Was hier fehlt ist eine Art Archivstruktur, die kein Problem damit hat, dass die Einträge unterschiedlich lang sind.
Andreas
  Mit Zitat antworten Zitat
BasilBavaria

Registriert seit: 18. Mai 2011
Ort: Niederbayern
22 Beiträge
 
Turbo Delphi für Win32
 
#8

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 15:01
Hab zur Zeit leider keinen Zugriff auf den Quellcode - aber die Datenstruktur sieht ungefähr aus Kopf so aus:

Code:
tKarte = record
     SNr    : integer;        
     ID     : Cardinal;    
     Del    : boolean;    
     KID    : Cardinal;  
     CDate  : TDateTime;
     L1,
     L2,
     L3,
     L4,
     L5,                   //echte Länge der Daten
     L6      : word;       //Längenfelder für 6 strings
     Titel  : string;     //255
     Info1   : string;     //255
     Info2   : string;     //255
     DokFile : string;     //L=1024
     WWWRef : string;     //L=1024
     Memo   : string;     //L=2048
     Termin : TDateTime;
     TStatus : byte;      
  end;
Im Ergebnis kommen dabei 4933 Byte raus.
L1-L6 haben die echte Feldlänge der nachfolgenden Strings zum Inhalt
Felder kleiner der definierten Länge werden künstlich erweitert auf die definierte Länge, in etwa Info1 := Erw(Edit1.Text,255)

Insofern dürfte sich kein Feld bzw. der ganze Stream von der Größe her ändern.

Das mit der Größenprüfung bau ich mal erweitert ein und meld mich dann wieder.

Danke und noch nen schönen Tach ...
  Mit Zitat antworten Zitat
Benutzerbild von rollstuhlfahrer
rollstuhlfahrer

Registriert seit: 1. Aug 2007
Ort: Ludwigshafen am Rhein
1.529 Beiträge
 
Delphi 7 Professional
 
#9

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 15:17
du könntest deine Struktur noch um 4 Bytes vornedran erweitern (4 Bytes = Integer). Dieser Integer gibt dann sicherheitshalber an, wie lange dein Datensatz ist. Die Länge musst du nicht verwenden, aber kannst dich im Fehlerfall schnell zwischen den Strukturen hin und her bewegen und diese auch in verschiedene Dateien splitten. Somit wären im Fehlerfal auch nicht gleich alle Daten weg.

aber die Datenstruktur sieht ungefähr aus Kopf so aus:

Code:
tKarte = record
     SNr    : integer;        
     ID     : Cardinal;    
     Del    : boolean;    
     KID    : Cardinal;  
     CDate  : TDateTime;
     L1,
     L2,
     L3,
     L4,
     L5,                   //echte Länge der Daten
     L6      : word;       //Längenfelder für 6 strings
     Titel  : string;     //255
     Info1   : string;     //255
     Info2   : string;     //255
     DokFile : string;     //L=1024
     WWWRef : string;     //L=1024
     Memo   : string;     //L=2048
     Termin : TDateTime;
     TStatus : byte;      
  end;
Autsch. Das Problem bei der Sache dürfte wohl sein, dass deine Strings wohl nicht immer die gleiche Länge haben
Ansonsten schöne Struktur. Kann man prima in eine DB speichern.

@Sir Rufo
für 20Kb gleich einen Feuervogel anschleppen?
Warum nicht. Dann hat die DB das Problem mit dem Speichern und die kann das. Außerdem könnten es ja mehr Daten werden.

Bernhard
Bernhard
Iliacos intra muros peccatur et extra!
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Nutzung MemoryStream und FileStream

  Alt 18. Mai 2011, 16:05
Du kannst/solltest statt "String" einen "ShortString" oder einen String[X] (X = 1 bis 255) benutzen.
Wenn dir für alle Felder maximal 255 Zeichen reichen, dann ist das kein Problem und das Laden & Speichern des Records wird ein Kinderspiel!

Edit: Ich sehe grade du hast auch längere Strings. Dann kannst du alternativ Array[0..Länge-1] of (Ansi)Char benutzen! Delphi behandelt die Arrays wie PChars und deswegen kannst du damit fast so arbeiten wie mit richtigen Strings!
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz