Autor |
Beitrag |
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Fr 19.07.13 11:20
Guten Tag,
ich habe mal eine Frage zu Stream.Write.. ich habe gegoogelt, aber irgendwie nur Stream Erklärungen bekommen...
Zuerst: Was ist der Unterschied zwischen Write und WriteBuffer? (abgesehen davon, dass Write eine Funktion ist und ein Integer zurückliefert)
2. : Was kann ich mit dem Rückgabewert von Write anfangen? bzw. was sagt er aus?
Ich denke, hierzu wurde schon einiges erklärt, deshalb würden mir Links oder Zitate natürlich vollkommen reichen... Aber ich finde nur Streamerklärungen und die Nutzung von Write.... Und egal auf welcher Seite ich schaue, es wird eigentlich immer Write benutzt ohne den Rückgabewert zu beachten... Warum dann nicht gleich WriteBuffer
Ich denke wenn ich Write/ Writebuffer verstanden habe, erschließt sich Read/ Readbuffer mir von selbst
mfG IHopeOnlyReader
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Christian213
Beiträge: 66
Erhaltene Danke: 3
Win XP, Win 7 64Bit
Lazarus 1.0.10
|
Verfasst: Fr 19.07.13 11:26
Hallo,
so wie ich die Beschreibung von Write und WriteBuffer verstehe, ist der Unterschied das Verhalten bei einem Fehler:
- Writerbuffer erzeugt eine Exception, wenn die mit "Count" angegebene Anzahl an Bytes nicht geschrieben werden kann.
- Write hingegen liefert die Anzahl der geschriebenen Bytes als Rückgabewert. Im Fall dass nichts geschrieben werden konnte, müsste dieser Wert dann 0 sein.
Zitat: |
Description Write:
Write attempts to write Count bytes from Buffer to the stream. It returns the actual number of bytes written to the stream.
This method should be used when the number of bytes that should be written is not determined. If a specific number of bytes should be written, use TSTream.WriteBuffer instead.
As implemented in TStream, Write does nothing but raises EStreamError exception to indicate that writing is not supported. Descendent classes that allow writing must override this method to do the actual writing.
Description WriteBuffer:
WriteBuffer writes Count bytes to the stream from Buffer. If the stream does not allow Count bytes to be written, then an exception is raised.
WriteBuffer should be used to read in a fixed number of bytes, such as when writing structures or the content of variables. If the number of bytes is not determined, use TStream.Write instead. WriteBuffer uses Write internally to do the actual reading.
|
Für diesen Beitrag haben gedankt: IhopeonlyReader
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Fr 19.07.13 11:32
ok vielen Dank
jedoch ist es dann nicht wie ich es vermutete:
IhopeonlyReader hat folgendes geschrieben : | Ich denke wenn ich Write/ Writebuffer verstanden habe, erschließt sich Read/ Readbuffer mir von selbst
|
Wieso sollte es einen Fehler beim lesen geben? (ok, wenn sizeof<Counter oder?)
und wie schreibt man konstante-chars/ zahlen in einen Stream?
muss man tatsähclich einer variablen den Wert der Konstanten zuweisen und die variable dann als Buffer übergeben? wenn ja warum nicht kann man nicht direkt die konstante, wie bei konstanten Strings übergeben? Moderiert von Narses: Beiträge zusammengefasstUnd warum soll man, bei unbekannter Größe Write und bei bekannter Größe ( ich denke mal SizeOf ist gemeint) Writebuffer verwenden?
oder verstehe ich den Satz
Zitat: | If the number of bytes is not determined, use TStream.Write instead
|
falsch?
Bei beidem muss ich doch ein Counter übergeben, der die Größe angibt, somit wäre doch immer nach dieser Nutzungsdefinition WriteBuffer zu verwenden?
Oder hängt das ganze damit zusammen, dass man bei "unbekannter Größe" nicht sicher sein kann, dass genug platz ist und man deshalb write benutzen soll, damit man weiß wie viel reingeschrieben werden konnte?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Christian213
Beiträge: 66
Erhaltene Danke: 3
Win XP, Win 7 64Bit
Lazarus 1.0.10
|
Verfasst: Fr 19.07.13 12:08
Einen wirklichen Vorteil sehe ich zumindest bei diesen Methoden auch nicht, zumal in der Beschreibung ja steht, dass intern doch wieder Write bzw. Read aufgerufen wird. Somit wird WriteBuffer auch nicht performanter sein.
Vielleicht hat ja jemand anderes hier Argumente für WriteBuffer und ReadBuffer.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Fr 19.07.13 12:13
ja ich selbst die Benutzerfreundlichkeit zum Verständnis des Fehlers bei writebuffer wird eine für den programmierer verständliche Fehlermeldung gegeben, bei write evt für den benutzer (je nach Programmierung)
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 19.07.13 14:15
Die meisten TStream Implementierungen können alle übergebenen Daten direkt verarbeiten. Das muss aber nicht so sein. Write versucht es aber einfach und gibt die Anzahl der im ersten Versuch erfolgreich geschriebenen Bytes zurück. WriteBuffer puffert die Daten zwischen, wenn nicht alle geschrieben werden konnten, und schreibt häppchenweise weiter. Eine Exception gibt es nur, wenn gar keine Daten mehr geschrieben werden können.
// EDIT: write korrigiert
Zuletzt bearbeitet von jaenicke am Sa 20.07.13 16:08, insgesamt 1-mal bearbeitet
Für diesen Beitrag haben gedankt: Christian213, Hidden, IhopeonlyReader
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Sa 20.07.13 15:37
Wenn write einen fehler gibt, dann widerspricht es doch der vorherigen aussage, dass es keine exceptions gibt, sondern entsprechend deshalb den Rückgabewert hat, wv geschrieben werden konnte...
und wenn writebuffer die Daten puffert ok... aber ich dachte es verwendet intern doch nur write..?
oder verwendet write writebuffer?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 20.07.13 16:08
IhopeonlyReader hat folgendes geschrieben : | Wenn write einen fehler gibt, dann widerspricht es doch der vorherigen aussage, dass es keine exceptions gibt, sondern entsprechend deshalb den Rückgabewert hat, wv geschrieben werden konnte... |
Stimmt, es liefert nur die Anzahl an Bytes, ggf. Null.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 21.07.13 17:56
Also sollte man lieber mit writebuffer arbeiten und die exception abfangen..
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
rushifell
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: So 21.07.13 22:40
Im Endeffekt spielt es keine Rolle, was du von beiden verwendest. Bei einem Stream.write sparst du Dir einen Try-Except-Block. Letztendlich ist es jedoch wohl Geschmackssache.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 21.07.13 22:54
Nach jaenicke puffert writebuffer die Daten doch zwischen und verhindert einen overstack, stimmt saß etwa nicht oder habe ich das falsch verstanden?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 22.07.13 06:36
IhopeonlyReader hat folgendes geschrieben : | Nach jaenicke puffert writebuffer die Daten doch zwischen und verhindert einen overstack, stimmt saß etwa nicht oder habe ich das falsch verstanden? |
Nicht bei allen Streams braucht man das, da es meistens eher so ist, dass es entweder klappt oder nicht. Dass ein Teil erfolgreich gesendet wird und danach der Rest dürfte eher die Ausnahme sein.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 22.07.13 19:56
Kannst du ein Beispiel nennen, wo es mit writebuffer klappt und
Mit write nicht?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 22.07.13 21:00
Socketkommunikation:
Je nach Komponente akzeptiert Write immer nur so viel wie in den aktuellen Buffer passt, so dass mit WriteBuffer nach und nach alles geschrieben wird.
Wobei die meisten Komponenten das auch intern schon gut behandeln.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Di 23.07.13 17:09
Also, wie gesagt sicherheitshalber writebuffer verwenden...
um nochmal zum Thema zu kommen, wie kann ich konstanten wie bytewerte (12) in einen Stream schreiben, als counter muss ich 1 angeben, klar aber was für die konstante? einen pointer auf die speicheradresse der konstante, oder wie? weil Stream.write(@konstante) ist einfacher als varx:=konstante; Stream.write( varx)
habe leider zur Zeit kein Delphi zur Hand, kann es deshalb nicht testen..
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mi 24.07.13 19:04
Push
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Mr_Emre_D
Beiträge: 114
Erhaltene Danke: 14
|
Verfasst: Mi 24.07.13 22:45
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mi 24.07.13 23:26
Danke es macht also keinen Unterschied ob write oder writebuffer..
Bei der konstanten also entweder @konstante, da die konstante aber mit der exe
Im ram liegt weiß ich nicht ob das mit einem pointer auf eine konstante so klappt... Falls es nicht klappt
Delphi-Quelltext 1: 2:
| Variable := konstante;Stream.write( @variable, sizeof( variable) ); |
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Mr_Emre_D
Beiträge: 114
Erhaltene Danke: 14
|
Verfasst: Do 25.07.13 00:17
Nein, wenn "const Buffer;" da steht, dann kannste einfache (nicht dynamische) Typen einfach übergeben!
Write(integer), Write(char), Write(Byte), ... klappt alles!
Write(String) wrid nicht gehen, da ein String intern ein (verschobener) Zeiger auf eine Struktur ist, in der u.A. steht, wie lang der String ist:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| type PInternalStringStruct = ^TInternalStringStruct; TInternalStringStruct = record RefCount: Integer; Length: Integer; Content: record end; end;
procedure main; var s1: String; begin s1 := 'Hello World!'; Writeln( 'RefCount: ', PInternalStringStruct(integer(s1)-8).RefCount, #13#10, 'Length: ', PInternalStringStruct(integer(s1)-8).Length, #13#10, 'First character: "', Char(Pointer(s1)^), '"'#13#10, 'Whole content: "', pChar(@PInternalStringStruct(integer(s1)-8).Content), '"'); Readln; end; |
Dh. Stream.Write(String) würde nur den Pointer reinschreiben (je nachdem, wie groß zu Count setzt!)
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Do 25.07.13 13:43
Achso, ich dachte Parameter ohne Typ wären untypsierte pointer.. Deshalb wollte ich pointer übergeben.. Naja ok also
Mal ein paar Beispiele, die ihr bitte auf korrektheit prüft
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| Stream.write( pointer(StringVariablen)^, length( StringVariable) ); Stream.write( shortstring, length( shortstring) ); Stream.write( einpackedrecord, sizeof( einpackedrecord) ); If length( DynArray) >= 1 Then Stream.write( dynArray, length( DynArray) * sizeofof( dynArray[0]) ); Stream.write( length( DynArray ), 4 ); |
Ich weiß, dass es zwar so nicht vernünftig auszulesen ist, da ich vor einen String die Länge des strings setzten sollte, aber es geht mir in diesem Beispiel darum, dass wirklich beim String der String drinsteht beim Array der arrayinhalt und nicht irgendwelche pointer...
Sind die Beispiele so richtig?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|