Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Streams: welche BufSize? (https://www.delphipraxis.net/81688-streams-welche-bufsize.html)

Cöster 1. Dez 2006 16:03


Streams: welche BufSize?
 
Hi!

Beim Arbeiten mit Streams rufe ich den Konstruktor von TWriter auf. Als Parameter erwartet er u.a. die Größe des Puffers. Welche Zahl muss ich da angeben? Kann man die berechnen? Wenn ja, wie?

himitsu 1. Dez 2006 16:27

Re: Streams: welche BufSize?
 
Am Besten du ließt dort einfach mit ^^

Dateien schreiben Buffergröße optimieren


[add]
oder mal auf den da unten hören :gruebel:

(Selber nutze ich "fast" nie Streams :angel: )

Der_Unwissende 1. Dez 2006 16:29

Re: Streams: welche BufSize?
 
Hi,
warum genau rufst du denn den Konstruktor von Writer auf? Da sagt doch die Delphi Hilfe extra zu:
Zitat:

Erzeugen Sie Writer-Objekte nicht direkt. Writer-Objekte werden von den Methoden der Stream-Objekte oder in globalen Routinen automatisch erzeugt, die das Streamen initiieren. Dies beinhaltet folgendes:
  • die globale Prozedur ObjectBinaryToText, die ein Writer-Objekt direkt erstellt.
  • die globale Funktion ReadComponentResFile, die ein Datei-Stream-Objekt erstellt, das seinerseits ein Writer-Objekt erstellt.
  • die Methode WriteDescendent von TStream, die ein Writer-Objekt erstellt.

Sobald die Streaming-Operation läuft, sollten Programme die Reader-Objekte nicht direkt bearbeiten. Die Methoden der Reader-, Writer- und Komponentenobjekte rufen sich automatisch gegenseitig auf.

Cöster 1. Dez 2006 17:41

Re: Streams: welche BufSize?
 
Zitat:

Zitat von himitsu
Am Besten du ließt dort einfach mit ^^

Dateien schreiben Buffergröße optimieren

Davon versteh ich ehrlich gesagt fast nur Bahnhof.

Zitat:

Zitat von himitsu
(Selber nutze ich "fast" nie Streams :angel: )

Warum nicht?

Zitat:

Zitat von Der_Unwissende
warum genau rufst du denn den Konstruktor von Writer auf?

Hm, weil das in einem Beispiel in der Schule auch so war. :gruebel:

Wie schreibt man folgenden einen Code, denn ohne direkt auf den Writer zuzugreifen?

Delphi-Quellcode:
procedure Save(const AFileName: string; Figure: Integer);
var
  F: TFileStream
  W: TWriter;
begin
  F := TFileStream.Create('MyFile.dat', fmCreate);
  W := TWriter.Create(F, 4000);
  W.WriteInteger(Figure);
  W.Free;
  F.Free;
end;

himitsu 1. Dez 2006 17:49

Re: Streams: welche BufSize?
 
Zitat:

Zitat von Cöster
Davon versteh ich ehrlich gesagt fast nur Bahnhof.

Du brauchst doch nur auf die Größenangaben zu achten :zwinker:

Zitat:

Zitat von Cöster
Warum nicht?

Is mir zu umständlich und 's gibt Besseres. :roll:


In deinem Beispile hat man 'nen extra Writer verwendet, aber in TFileStream sollte doch wohl schon einer drin sein? :gruebel:

Schau mal in der OH nach TFileStream ... dort müßte es Funktionen mit den Wörtern Read und Write im Namen geben :zwinker:

Delphi-Quellcode:
procedure Save(const AFileName: string; Figure: Integer);
var
  F: TFileStream;
begin
  F := TFileStream.Create('MyFile.dat', fmCreate);
  F.Write...(Figure, SizeOf(Figure));
  // oder  F.Write...(Figure, 4);
  F.Free;
end;
bei "..." kann es sein, daß dort noch irgendwas hin muß, z.B. WriteBuffer, oder so, aber da kann dir die OH besser helfen.


PS: bei einem Integer (4 Byte) dürfte eine 4 auch schon reichen, oder du läßt es so, wie es ist :angel:

Der_Unwissende 1. Dez 2006 17:54

Re: Streams: welche BufSize?
 
Zitat:

Zitat von Cöster
Wie schreibt man folgenden einen Code, denn ohne direkt auf den Writer zuzugreifen?

Delphi-Quellcode:
procedure Save(const AFileName: string; Figure: Integer);
var
  F: TFileStream
  W: TWriter;
begin
  F := TFileStream.Create('MyFile.dat', fmCreate);
  W := TWriter.Create(F, 4000);
  W.WriteInteger(Figure);
  W.Free;
  F.Free;
end;

Na ja, eigentlich schreibst du halt in den Stream:
Delphi-Quellcode:
procedure Save(const AFileName: string; Figure: Integer);
var
  F: TFileStream
  W: TWriter;
begin
  F := TFileStream.Create('MyFile.dat', fmCreate);
  try
    F.Write(Figure, sizeOf(Figure));
  finally
    F.Free;
  end;
end;
Das try...finally Gebilde ist dabei ein Schutzblock. Da du den Stream öffnest solltest du immer dafür sorgen, dass der (eben auch bei Fehlern) geschlossen wird. Alles was unter finally kommt wird immer ausgeführt (egal ob es Fehler gab oder nicht). In einen Stream ganz du jedes Datum ganz untypisiert schreiben, dabei werden wirklich die rohen Bytes geschrieben. sizeOf gibt dir die Größe eines Datums in Byte an. Das klappt zwar gut für primitive Datentypen (Zahlen, Character) und Records, aber nicht mehr für Strings und dyn. Arrays. Bei diesen musst du die Länge mit der Größe eines Elements multiplizieren (length(x) * sizeOf(x[0])), bei Strings kannst du einfach die Länge nehmen. Schreibst du ein dyn. Array in einen Stream, so musst du dort das erste Element (x[0]) übergeben, nicht nur x (x ist das dyn. Array), bei einem String gilt das Selbe, allerdings ist der Index des ersten Elements im String immer 1 statt 0.

Gruß Der Unwissende

Cöster 1. Dez 2006 19:33

Re: Streams: welche BufSize?
 
Erstmal danke für das, was ihr beide bisher geschrieben habt.

Zitat:

Zitat von himitsu
Is mir zu umständlich und 's gibt Besseres. :roll:

Zum Beispiel? Ini-Files oder typisierte Dateien halte ich oft für umständlicher. Aber woran hast du denn eigentlich gedacht?

Zitat:

Zitat von Der_Unwissende
Schreibst du ein dyn. Array in einen Stream, so musst du dort das erste Element (x[0]) übergeben, nicht nur x (x ist das dyn. Array), bei einem String gilt das Selbe

Hm? Für welchen Parameter muss ich das jetzt angeben? Bei der Größe hab ich dich so verstanden, dass man Length(Array)*SizeOf(Array[0]) angibt, bei einem String nur Length(String), was mir auch logisch erscheint, weil 1 Buchstabe ja 1 Byte groß ist. Für den Buffer erschiene es mir aber auch unlogisch, wenn ich nicht den ganzen String übergebe, sondern nur den ersten Buchstaben. Bin ich jetzt blöd?

Wie mach ich das dann beim Lesen, wenn ich nen String hab? Dann weiß ich ja nicht von vornherein, wie viele Bytes er im Stream einnimmt.

Muetze1 1. Dez 2006 22:12

Re: Streams: welche BufSize?
 
@Der_Unwissende: Wenn man eigene Streams baut bzw. binäre Streams, dann sind die TWriter und TReader Klassen richtig gut nutzbar. Auch weil sie die Datenstruktur dynamisch optimieren und damit bekommt man gute Binärdaten hin. In der Hilfe ist dies vermerkt, damit keiner auf die Idee kommt damit direkt zu hantieren, sie sind aber schon seit sehr vielen Delphi Versionen dafür nutzbar. Schon allein durch die Typüberprüfung und auch automatischen Konvertierungen, ist es ein gutes System. Vor allem ist es bequemer als die Hexereien mit den TStream Nachfahren direkt.

negaH 2. Dez 2006 10:46

Re: Streams: welche BufSize?
 
ich stimme Thomas absolut zu, meine Meinung ;)

Also nicht immer gleich vor Allem zurückzucken nur weil irgendeiner sagt tue das nicht ! Alles was in der RTL und VCL verfügbar ist kann man nutzen.

Allerdings erzeugt das Stream Format der TWriter/TReader Klassen auch einen Overhead in der Größe der geschriebenen Daten. Ein direktes binäres Schreiben in den Stream ist also kompakter und die TWriter Klasse hätte nur 4 Vorteile:

1.) typsicheres Auslesen der Daten, man kann keinen String lesen wo ein Integer geswchrieben wurde
2.) der binäre Stream kann über ObjectBinaryToText() in einen Text formatierten Stream umgewandelt werden, so wie bei binären DFMs und textorientierten DFMs
3.) hierarische Datenstrukturen sind möglich, sprich gruppierte und gekapselte Datenstrukturen
4.) man kann alle Nachfahren von TPersistent in diesen Stream speichern und laden, dh. alle published Properties werden autom. erkannt und gespeichert, wie auch die Zeiger-Refrerenzen der Klassen aufgelösst (eventl. Aufruf von RegisterClasses() nötig)

Also schon einige Vorteile, aber das Hauptproblem mit geänderten Datenstruktur-Aufbau bleibt bestehen wie bei binären Streams.

Gruß Hagen

Muetze1 2. Dez 2006 11:49

Re: Streams: welche BufSize?
 
Zitat:

Zitat von negaH
ich stimme Thomas absolut zu, meine Meinung ;)

Danke, das geht runter wie Öl... :???:

Zitat:

Zitat von negaH
Also schon einige Vorteile, aber das Hauptproblem mit geänderten Datenstruktur-Aufbau bleibt bestehen wie bei binären Streams.

Da kann man noch eine Versionsnummer am (relativen) Anfang des Streams einführen und auch dies damit abhandeln - oder BitFelder und Grössenfelder um das sogar noch mit alten kompatibel zu machen. Gibt viele Möglichkeiten dies auch so gut wie es geht auszuschalten...


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:59 Uhr.
Seite 1 von 2  1 2      

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