Autor Beitrag
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Christian213
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Fr 19.07.13 11:32 
ok vielen Dank :)

jedoch ist es dann nicht wie ich es vermutete:
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconNarses: Beiträge zusammengefasst

Und 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Christian213
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66
Erhaltene Danke: 3

Win XP, Win 7 64Bit
Lazarus 1.0.10
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Fr 19.07.13 12:13 
ja ich selbst :D die Benutzerfreundlichkeit zum Verständnis des Fehlers :D 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 20.07.13 16:08 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 21.07.13 17:56 
Also sollte man lieber mit writebuffer arbeiten und die exception abfangen..

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
rushifell
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 22.07.13 06:36 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mo 22.07.13 19:56 
Kannst du ein Beispiel nennen, wo es mit writebuffer klappt und
Mit write nicht?

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mi 24.07.13 19:04 
Push

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Mr_Emre_D
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 114
Erhaltene Danke: 14



BeitragVerfasst: Mi 24.07.13 22:45 
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function Write(const Buffer; Count: Integer): Integer; virtual; abstract;

---

Introduces a pure virtual method for writing to the stream. 

Each descendant stream object defines a Write method that writes data to its particular storage
medium (such as memory or a disk file). Write attempts to write up to Count bytes from Buffer,
and returns the number of bytes actually written. 

All the other data-writing methods of a stream (WriteBuffer, WriteComponent) call Write to do their actual writing.


ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure WriteBuffer(const Buffer; Count: Integer);

---

Writes Count bytes from Buffer onto the stream and advances the current position of the stream by Count bytes. 

Use WriteBuffer to save data to a stream. WriteBuffer and ReadBuffer are used in cases where the number
of bytes is known and required, for example when reading in structures. Use WriteBuffer for standard
file I/O streaming. 

WriteBuffer is used internally for writing to a stream and copying from a stream. It is used by other objects,
such as strings and lists, for writing strings stored in a buffer. 

WriteBuffer calls Write to handle the actual writing. If the stream fails to write all the requested bytes,
an EWriteError exception is raised.


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TStream.WriteBuffer(const Buffer; Count: Longint);
begin
  if (Count <> 0and (Write(Buffer, Count) <> Count) then
    raise EWriteError.CreateRes(@SWriteError);
end;


Zu deiner letzten Frage - aus den Funktionsrümpfen (const Buffer;) sollte die Antwort nun ersichtlich sein!
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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
ausblenden Delphi-Quelltext
1:
2:
Variable := konstante;//wenn konstante ein Char oder Byte, Word... Ist
Stream.write( @variable, sizeof( variable)  );

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Mr_Emre_D
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 114
Erhaltene Danke: 14



BeitragVerfasst: 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Stream.write( pointer(StringVariablen)^, length( StringVariable) ); // Bei normalen String
Stream.write( shortstring, length( shortstring)  ); // bei shortstring wie String[10]
Stream.write( einpackedrecord, sizeof( einpackedrecord)  );
If length( DynArray) >= 1 Then
      Stream.write( dynArray, length( DynArray)  * sizeofof( dynArray[0]) );
Stream.write( length( DynArray ), 4 ); // length liefert ein integer also 4 byte

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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!