2010-09-20 4 views
11

BinaryReader hat keine EndOfStream-Eigenschaft. Ist es sicher, folgenden Code zu verwenden, um zu überprüfen, ob das Ende des Streams erreicht ist?EndOfStream für BinaryReader

reader.BaseStream.Length>reader.BaseStream.Position

+0

Welche Art von Stream? Nicht alle Streams kennen ihre Länge im Voraus. –

Antwort

7

Es hängt davon ab. Es gibt verschiedene Stream-Typen, die die Eigenschaft "Length" oder "Position" nicht implementieren. Sie erhalten eine NotSupportedException. Zum Beispiel NetworkStream. Natürlich, wenn Sie einen solchen Stream verwenden, dann müssen Sie wirklich im Voraus wissen, wie oft Sie die BinaryReader.Read() Methode aufrufen. Also, ja, es ist in Ordnung.

+1

Dies ist nicht universell ... Es kann vorkommen, dass Sie bis zum Ende eines NetworkStream lesen müssen (was passiert, wenn die andere Seite die Verbindung schließt). – torvin

+0

Erwartung ist, dass sich die andere Seite schön verabschiedet. Wenn dies nicht der Fall ist, ist die Ausnahme, die Sie beim Lesen einer geschlossenen Verbindung erhalten, sicherlich universell. –

-1

Das ist, was ich immer in der Vergangenheit getan habe, und ich habe noch nie ein Problem mit ihm gesehen. Der verwendete Code befindet sich seit 2 Jahren in einer Produktionsumgebung.

+5

Probieren Sie es auf einem DeflateStream irgendwann. . . –

+0

Und mit welcher Art von Stream? –

+0

@Jim Ich wusste das nicht. Das sind gute Informationen, danke. Henks Antwort erhält dann +1. –

2

Dies funktioniert nicht als allgemeine Lösung, da davon ausgegangen wird, dass der BaseStream-Wert die Length-Eigenschaft unterstützt. Viele Stream Implementierung nicht und stattdessen werfen Sie eine NotSupportedException. Insbesondere ist jeder Netzwerkbasisstrom, wie und NetworkStream

10

Der einfachste Weg, den ich gefunden habe, ist, den zurückgegebenen Wert der PeekChar() - Methode des BinaryReader zu überprüfen. Wenn es -1 zurückgibt, haben Sie das Ende des Streams erreicht.

+1

Dies funktioniert, wenn der zugrunde liegende Stream das Suchen nicht unterstützt. –

+0

Ja, ich habe auch herausgefunden, dass in der Praxis, wenn Sie 'PeekChar()' oft aufrufen, kann es sehr langsam sein, wenn Sie mit Dateien umgehen. –

+0

Es scheint auch eine Ausnahme auszulösen, wenn die Daten an dieser Position ein ungültiges Zeichen sind. Manchmal bekomme ich das: 'System.ArgumentException: Der Ausgabe-Zeichenpuffer ist zu klein, um die decodierten Zeichen zu enthalten, die 'Unicode (UTF-8)' Fallback 'System.Text.DecoderReplacementFallback'.codieren –

1

Ich habe festgestellt, dass der Vergleich von Position zu Länge NICHT mit StreamReader funktioniert, auch wenn der zugrunde liegende BaseStream die Suche unterstützt. Es scheint, dass StreamReader Read-Ahead von BaseStream puffert. Dies ist der Grund, warum StreamReader eine EndOfStream-Eigenschaft bereitstellt, was eine gute Sache ist, und ich wünschte, BinaryReader hätte das Gleiche getan.

Die Überprüfung dieser Werte (Länge und Position) auf dem zugrunde liegenden Basisstrom zählt auf BinaryReader nicht wie StreamReader, d. H. Setzt BinaryReader nur die genaue Anzahl der Bytes von BaseStream benötigt, um einen Benutzermethodenaufruf zu erfüllen. Vermutlich, wenn BinaryReader tatsächlich intern so arbeitet, ist es der Grund, warum es keinen EndOfStream liefern muss, aber ich wünschte, es hätte einen geliefert, sodass ich wusste, dass das Ende der Datei für Clients in einer implementierungsunabhängigen Weise korrekt gehandhabt wurde.

Natürlich sind Lesegeräte keine Streams, aber in Bezug auf das Ende der Datei wäre es nett, wenn es eine gemeinsame Schnittstelle gäbe, die es Clients von Eingabe-/Ausgabeklassen ermöglicht, zu wissen, ob A. Ende der Datei ein sinnvolles Konzept ist die zugrunde liegende Quelle von Daten und B. wenn das Ende der Datei auftritt, wenn A sinnvoll ist.

0

Überprüfen Sie die Streams CanSeek-Eigenschaft. Wenn diese Eigenschaft true zurückgibt, können Sie die Länge des Streams mit der Position des Streams vergleichen, um festzustellen, ob Sie sich am Ende des Streams befinden. Wenn diese Eigenschaft false zurückgibt, funktioniert das nicht.

Bei Netzwerkstreams müssen Sie möglicherweise zwischen dem Ende der verfügbaren Bytes unterscheiden (der Client am anderen Ende hat noch mehr zu schreiben, aber noch nicht) und der Stream wird geschlossen. Die IsConnected-Eigenschaft für eine zugrunde liegende Tcp-Verbindung ist nicht zuverlässig, wenn der Stream geschlossen wurde. Es ist möglich, die Verbindungen aufzulisten, die der Computer hat, und festzustellen, ob der von Ihnen verwendete Datenstrom darunter ist. Dies ist zuverlässiger, aber komplexer. Es kann besser sein, nur IOExceptions zu behandeln, wenn Sie nicht lesen können