AGB  ·  Datenschutz  ·  Impressum  







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

Stream auslesen

Ein Thema von PASST · begonnen am 9. Feb 2006 · letzter Beitrag vom 10. Feb 2006
Antwort Antwort
Seite 1 von 2  1 2      
PASST

Registriert seit: 30. Mär 2005
Ort: Krefeld
325 Beiträge
 
Delphi 7 Enterprise
 
#1

Stream auslesen

  Alt 9. Feb 2006, 18:00
Hi NG.

Delphi 4 (update 3)

Ich versuche gerade zu verstehen, wie ich Daten aus einem Stream auslesen kann.
Dazu habe ich folgenden Beitrag gefunden, insb. ->Antwort#15. Dort hat SirThornberry Code als Bsp. gepostet. Dabei verstehe ich das Auslesen nicht.
Delphi-Quellcode:
SetLength(LBuffer2, 50);
LBytes := AStream.Read(LBuffer2[1], 50);
LBuffer := copy(LBuffer2, 1, LBytes);
Dass es funktioniert, habe ich durch Nachbauen festgestellt. Mir fehlt es aber anscheinend an Grundlagen.
Warum muss ich für LBuffer2 die Länge vordefinieren? Im Read wird doch vorgegeben, dass ich 50 Bytes lesen will.
Warum muss ich anschließend das ganze in eine zweite Variable LBuffer umkopieren? Wenn das Read weniger als 50 Bytes liefert, also LBytes, macht das schon Sinn. Aber was ist, wenn das Stream ausreichend Bytes enthält?

Ihr merkt, ich bin bzgl Stream und Zeiger ein Anfänger. Ich habe mir auch schon das Tutorial auf DSDT.info dazu durchgelesen, komme aber immer noch nicht wirklich damit zurecht.

Klärt mich bitte auf
Gruß
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#2

Re: Stream auslesen

  Alt 9. Feb 2006, 18:06
Zitat von PASST:
Warum muss ich für LBuffer2 die Länge vordefinieren? Im Read wird doch vorgegeben, dass ich 50 Bytes lesen will.
Der Stream kann aber nicht wissen, dass du einen String übergibst und deshalb nicht SetLength selbst aufrufen. Für das "Auffangbecken" bist du selbst zuständig.
Zitat:
Warum muss ich anschließend das ganze in eine zweite Variable LBuffer umkopieren? Wenn das Read weniger als 50 Bytes liefert, also LBytes, macht das schon Sinn.
Genau.
Zitat:
Aber was ist, wenn das Stream ausreichend Bytes enthält?
Dann wird der String eben sinnlos herumkopiert, ist das denn so schlimm ?
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
PASST

Registriert seit: 30. Mär 2005
Ort: Krefeld
325 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Stream auslesen

  Alt 9. Feb 2006, 18:24
Zitat:
Der Stream kann aber nicht wissen, dass du einen String übergibst und deshalb nicht SetLength selbst aufrufen.
Dafür deklariere ich LBuffer doch vorher als String.
Wenn ich nicht mit Streams arbeite, gebe ich doch bei einer String-Variable auch nicht vorher die Länge vor, sondern setze einfach: sText := 'Abc'

Zitat:
Dann wird der String eben sinnlos herumkopiert, ist das denn so schlimm?
Nein, schlimm ist das nicht. Aber ich erhalte in jedem Fall einen RuntimeError, wenn ich auf das Kopieren verzichte - obwohl ausreichend Bytes vorhanden sind.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Stream auslesen

  Alt 9. Feb 2006, 18:47
Zitat von PASST:
Zitat:
Der Stream kann aber nicht wissen, dass du einen String übergibst und deshalb nicht SetLength selbst aufrufen.
Dafür deklariere ich LBuffer doch vorher als String.
Jupp und damit ist das Auffangbecken nur als Name vorhanden. Und Namen sind ja bekanntlich nur Schall und Rauch. Wenn du in so ein Auffangbecken was reinschüttest, schüttest du es ins nichts. Mit dem Aufruf von SetLength gibst du dem Auffangbecken jetzt ein Größe und du kannst was reinschütten. Und das geht weil ein String auch nur ein dynamisches Array vom Typ Char ist mit etwas Primboriom zum Verwalten (Länge etc.) drumrum. In ein dynamisches Array der Länge null kannst du auch nichts reinschreiben.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
PASST

Registriert seit: 30. Mär 2005
Ort: Krefeld
325 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Stream auslesen

  Alt 9. Feb 2006, 19:59
Was ist denn dann der Unterschied zwischen der Verwendung eines String auf diese Weise [sText := 'Abc'] oder wie ich es für ein Stream machen muss?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Stream auslesen

  Alt 9. Feb 2006, 20:03
Die Methode Read erwartet einen Zeiger auf eine Speicheradresse und wie Khabarakh schon sagt:
Zitat:
Der Stream kann aber nicht wissen, dass du einen String übergibst und deshalb nicht SetLength selbst aufrufen.
Bei der Zuweisung einer Zeichenkette an eine Stringvariable kann der Compiler intern SetLength aufrufen, weil er weiß, dass es sich um einen String handelt - du hast es ja selber so deklariert.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#7

Re: Stream auslesen

  Alt 9. Feb 2006, 20:07
Zitat von PASST:
Was ist denn dann der Unterschied zwischen der Verwendung eines String auf diese Weise [sText := 'Abc'] oder wie ich es für ein Stream machen muss?
Der Stream schreibt ab dem übergebenen Pointer munter in den Speicher. Wo dein String aufhört, ist ihm egal, er kann es ja gar nicht wissen. Falls nicht sowieso eine AV ausgelöst wird, kannst du eben über den String nur auf den Teil innerhalb des Strings zugreifen. Hinterher SetLength aufzurufen würde übrigens auch nichts bringen, da ein komplett anderer Speicherplatz für den neuen String verwendet wird.
Das Literal wird vom Compiler zur Compiletime ausgewertet. Es wird sozusagen eine Konstante angelegt, die Zeichenkette auf die Länge analysiert und das Literal mit genau dieser Länge erstellt.

[edit] Der rote Kasten hat mich verlassen [/edit]
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Stream auslesen

  Alt 9. Feb 2006, 20:10
Zitat von Khabarakh:
[edit] Der rote Kasten hat mich verlassen [/edit]
Macht nichts, war doch eine schöne Ergänzung zu meinem Posting.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#9

Re: Stream auslesen

  Alt 9. Feb 2006, 20:21
Zitat von Luckie:
Zitat von Khabarakh:
[edit] Der rote Kasten hat mich verlassen [/edit]
Macht nichts, war doch eine schöne Ergänzung zu meinem Posting.
Dann hätte ich meinen Post aber noch besser auf deinen abstimmen können .
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Stream auslesen

  Alt 9. Feb 2006, 20:21
im übrigen ist folgendes effektiver:
Delphi-Quellcode:
SetLength(LBuffer1, 50);
LBytes := AStream.Read(LBuffer1[1], 50);
SetLength(LBuffer, LBytes);
Ich versuch das ganze auch mal zu erklären.
"AStream.Read" macht intern nicht etwa eine Zuweisung wie "a := 'abc'" sondern AStream.Read kopiert letztendlich zeischen von einer Stelle an eine andere Stelle im Speicher.
Du könntest also
AStream.Read(Pointer(20)^, 50); schreiben und damit versuchen an die Adresse "20", 50 Bytes aus dem Stream zu kopieren. Als Ergebnis wird dir dann jedoch eine Fehlermeldung wie "Zugriffsverletzung an Adresse 000020" oder so ausgegeben.
AStream.Read erwartet also einfach eine Adresse (dereferenziert) so es Daten hinschreiben kann.

Als Bildlisches Beispiel. Du bestellst eine LKW-Ladung Sand uns sagst dem LKW-Faherer wo er das ganze abladen soll. Der LKW wird dann an die entsprechende stelle gefahren und kippt dort den Sand ab. Dem LKW-Fahrer ist es dabei egal ob er das ganze in einen Sandkasten ablädt der eventuell zu klein ist oder auf das Grundstück deines Nachbarn, er lädt es dort hinn wo du es sagst. Und genau so verhält es sich mit dem "Stream.Read" es lädt die Bytes an die Stelle im Speicher die du angibst. Der Vorteil ist das man bei Stream.Read jeden Variablentyp nutzen kann. Wenn es speziel für bestimmte Datentypen (String, Integer, Byte,...) eine Extra funktion gäbe würde man schnell an die grenzen stoßen da ja auch jemand neue Datentypen definieren will die natürlich auch gelesen werden sollen.

Wie dir eventuell auch schon aufgefallen ist hat der erste Parameter von "Stream.Read" keinen Typ, das heißt innerhalb der Funktion kann man nicht einfach
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  ShowMessage(Buffer);
schreiben weil Buffer kein String ist
und auch
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  ShowMessage(inttostr(Buffer));
geht nicht weil Buffer auch kein Integer ist. Buffer ist undefiniert und wird deshalb einfach als Pointer behandelt.

Folgendes geht jedoch:
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  Integer(Buffer) := 5;
damit würde man durch den Cast dem Compiler mitteilen das buffer als Integer zu behandeln ist. Da es aber nich in jedem fall ein Integer ist kann man sowas nicht schreiben und daher wird das ganze einfach als pointer behandelt. Obiges ist also nix anderes als
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  Pinteger(@Buffer)^:= 5;
Da innerhalb der Funktion ja nicht bekannt ist welcher Typ "Buffer" ist kann somit auch nicht festgestellt werden wie groß der Eventuelle String ist (weil ja nichtmal bekannt ist das es ein String ist) und deshalb musst du vorher den Speicher für den String besorgen (mit SetLength) und dann bei Stream.Read angeben wie groß der verfügbate Speicher ist (der zweite Parameter).

Wenn du in deinem Quelltext an irgend einer Stelle folgendes hast:
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
var LString: String;
begin
  LString := '123456';
so weiß der compiler das '123456' 6 Zeischen lang ist und reserviert automatisch den Speicher was im in dem fall mit dem Stream aber nicht möglich ist da ja nicht bekannt ist wieviel zeischen wirklich zugewiesen werden.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 03:06 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