Stream Lesen bis tatsächliches Ende erreicht ist

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Stream Lesen bis tatsächliches Ende erreicht ist

    Hallo Zusammen,

    ich habe folgendes Problem: Von einem externen Gerät bekomme ich verschiedene Informationen in sehr kurzen Abständen per Netzwerkstream zugesandt. Bei den Informationen handelt es sich im Grunde um eine Zeichenfolge/String mit unterschiedlichen Längen. Hier mal 2 Beispiele:

    1. TM=CSVRs;SV=10010;EM;
    2. TM=PD;SV=10010;TD=1010,1012,;TS=11:22:44;EM;

    Durch meine bisherigen Code erhalte ich diese Nachrichten zwar, allerdings nur Puffer weise. Heißt ich bekomm nur einen String Block geliefert mit mehreren Datensätzen sobald der Puffer voll ist.

    Ich benötige jedoch immer nur einen einzelnen Datensatz der immer mit "TM=" anfängt und mit "EM;" aufhört.

    Hier mein bisheriger Lösungsansatz:

    VB.NET-Quellcode

    1. Dim myReadBuffer(1024) As Byte
    2. Dim myCompleteMessage As StringBuilder = New StringBuilder()
    3. Dim numberOfBytesRead As Integer = 0
    4. numberOfBytesRead = con.streamr.BaseStream.Read(myReadBuffer, 0, myReadBuffer.Length)
    5. myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead))


    Hat jemand einen Lösungsansatz für mich. Hab Google schon durchforstet aber leider nichts passendes Gefunden :(

    Viele Grüße,
    Nevs08
    Kannst Du nicht stattdessen per ReadToEnd einfach alles auslesen und den entstehenden Text an den passenden Sollbruchstellen splitten?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Nevs08 Dan musst Du in einer inneren Schleife permanent lesen und alle Zeichen zu einem String zusammensetzen.
    Immer, wenn ein Block-Ende Zeichen kommt, trennst Du den Block vom Anfang des Strings und sendest ein Event mit diesem Block an den Aufrufer.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    sendest ein Event mit diesem Block an den Aufrufer
    Auch nicht schlecht, das über Events zu machen.
    Meine übliche Methode ist, die Daten in eine Queue zu schreiben, die dann von irgendjemand abgearbeitet werden kann.

    Nevs08 schrieb:

    verschiedene Informationen in sehr kurzen Abständen per Netzwerkstream zugesandt
    Sind die einzelnen Telegramme nicht durch ein Sonderzeichen (z.B. Linefeed) voneinander getrennt?
    Kommt da tatsächlich am Stück ...;EM;TM=...?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    die Daten in eine Queue zu schreiben
    die müsste dann ja auch wieder gepollt werden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    petaod schrieb:

    Sind die einzelnen Telegramme nicht durch ein Sonderzeichen (z.B. Linefeed) voneinander getrennt?
    Kommt da tatsächlich am Stück ...;EM;TM=...?


    Ja das kommt tatsächlich am Stück. Leider.

    Aus dem Rest was noch geschrieben wurde werde ich leider nicht ganz schlau. Wie baue ich so eine Queue am besten auf?
    Hi
    lies in einer Schleife einfach die Daten in einen Byte-Puffer, konvertiere diesen in einen Char-Puffer (Encoding hilft dir da, sodass du nicht die ganze Zeit ein neues Char-Array erstellen musst) und gehe die Zeichen in diesem Char-Array durch. Werte anschließend die Chars au und zwar so, dass du Events herausgeben kannst.
    Die Bytes, die nicht in Chars konvertiert wurden, kopierst du anschließend an den Anfang des Puffers und liest im nächsten Vorgang an dieser Stelle weiter ein (offset wird entsprechend angepasst). Du behältst somit Char- und Byte-Puffer gleichzeitig. Stream.Read gibt dir ja die Anzahl der gelesenen Bytes zurück, Encoding.GetChars eben entsprechen die Zahl der Chars, die daraus erstellt werden konnten. Ich schätze allerdings, dass du ohne Encoding.GetByteCount nicht auf die Zahl der effektiv konvertierten Bytes kommst. Das scheint etwas blöd implementiert zu sein.

    Falls es sich um ASCII handelt, hast du das Problem mit den überstehenden Bytes übrigens nicht.

    Viele Grüße
    ~blaze~
    Alles klar danke für den Tipp blaze :)

    Noch kurze zwischen Frage wo ich glaube ich entweder am Schlauch stehe oder einfach zu Blöd bin: Mit

    VB.NET-Quellcode

    1. Dim myReadBuffer(1024) As Byte
    kann ich doch insgesamt 1024 ASCII zeichen speichern oder?

    Nevs08 schrieb:

    oder?
    1025 unter VB.NET, bei C# wären es 1024.
    Da musst Du aufpassen, was Du beim Lesen als Size eingibst, arbeite mit .Length.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!