Ich habe eine allgemeine Socket-Implementierung, die aus einem OutputStream und einem InputStream besteht.
Nachdem ich etwas Arbeit gemacht habe, schließe ich den OutputStream.
Wenn dies gemacht wird, gibt die read () - Methode von InputStream -1 für eine unendliche Zeitspanne zurück, anstatt eine Ausnahme zu erzeugen, wie ich es erwartet hatte.
Ich bin mir jetzt nicht sicher, welcher Weg am sichersten ist. Deshalb habe ich ein paar Fragen:
Danke!
Das -1 ist das erwartete Verhalten am Ende eines Streams. Siehe InputStream.read()
:
Liest das nächste Datenbyte aus dem Eingabestream. Das Wertbyte wird als int im Bereich von 0 bis 255 zurückgegeben. Wenn kein Byte verfügbar ist, weil das Ende des Streams erreicht wurde, wird der Wert -1 zurückgegeben. Diese Methode blockiert bis zur Eingabe der Daten verfügbar ist, das Ende des Streams erkannt wird oder eine Ausnahme ausgelöst wird.
Sie sollten natürlich weiterhin IOException
für unerwartete Ereignisse abfangen.
Kann ich sicher annehmen, dass -1 nur zurückgegeben wird, wenn der Stream geschlossen ist?
Ja.
Sie sollten solche Dinge nicht annehmen . Sie sollten das Javadoc lesen und implementieren, wie sich die API verhält. Vor allem, wenn Sie möchten, dass Ihr Code robust (oder "sicher" ist, wie Sie es nennen).
Nachdem das gesagt wurde, ist mehr oder weniger das, was der Javadoc in diesem Fall sagt. (Man könnte argumentieren, dass EOF und "Stream wurde geschlossen" nicht notwendigerweise das Gleiche bedeuten ... und dass das Schließen des Streams durch Aufruf von InputStream.close()
oder Socket.close()
lokal anders sein wird Dies ist jedoch für Ihren Anwendungsfall nicht direkt relevant.)
Gibt es keine Möglichkeit, die IO-Ausnahme neu zu erstellen, die auftritt, wenn die Verbindung gewaltsam unterbrochen wird?
Nein. Für den Anfang wird normalerweise keine Ausnahme an erster Stelle geworfen, so dass typischerweise nichts "neu erstellt" werden muss. Zweitens ist die Information in der ursprünglichen Ausnahme (falls es jemals eine gab) weg.
Soll ich ein Paket senden, das meinem InputStream sagt, dass es statt der beiden vorherigen Methoden schließen soll?
Nein. Die beste Methode besteht darin, das Ergebnis des Aufrufs read
zu testen. Sie müssen es trotzdem testen, da Sie nicht davon ausgehen können, dass die Methode read(byte[])
(oder was auch immer) die Anzahl der tatsächlich angeforderten Bytes zurückgegeben hat.
Ich nehme an, dass das Werfen einer anwendungsspezifischen Ausnahme unter bestimmten Umständen OK ist.
Denken Sie jedoch an den allgemeinen Grundsatz, dass Ausnahmen nicht für die normale Flusskontrolle verwendet werden sollten.
Eine der anderen Antworten schlägt vor, einen Proxy-InputStream zu erstellen, der eine Ausnahme auslöst, statt -1 zurückzugeben.
IMO, das ist eine schlechte Idee. Sie erhalten eine Proxy-Klasse, die sich als InputStream
ausgibt, aber den Vertrag der read
-Methoden verletzt. Das könnte zu Problemen führen, wenn der Proxy an etwas übergeben wurde, das eine korrekt implementierte InputStream
erwartet.
Zweitens, InputStream
ist ein abstract class
nicht ein interface
, daher funktioniert der dynamische Proxy-Mechanismus von Java nicht. (Zum Beispiel die newProxyInstance
Methode erfordert eine Liste von Schnittstellen, keine Klassen.
Entsprechend% %%%% javadoc gibt InputStream
zurück:
das nächste Datenbyte oder -1, wenn das Ende des Streams erreicht ist.
Sie können also davon ausgehen, dass es besser ist, das zu verwenden, was in der API angegeben ist, als eine Ausnahme zu versuchen und neu zu erstellen, da die ausgelösten Ausnahmen implementierungsabhängig sein können.
Wenn Sie den Outputs Stream in einem Socket schließen, wird der Socket selbst geschlossen.
Das sagt der JavaDoc für Socket:
public OutputStream getOutputStream () löst IOException
aus %Vor%stream delegiert alle seine Operationen zum Kanal. Wenn der Kanal in ist nicht blockierenden Modus dann die Ausgabe Schreibvorgänge des Streams werden werfen eine IllegalBlockingModeException.
%Vor%oder wenn der Sockel nicht angeschlossen ist.
Ich bin mir nicht sicher, ob Sie das wirklich wollen.
Gibt es keine Möglichkeit, die IO-Ausnahme neu zu erstellen, die auftritt, wenn die Verbindung gewaltsam unterbrochen wird?
Ich werde das beantworten. InputStream ist nur eine Schnittstelle. Wenn Sie wirklich wollen, dass die Implementierung eine Ausnahme auf EOF wirft, stellen Sie einen eigenen kleinen Wrapper bereit, überschreiben Sie read () s und werfen Sie eine Ausnahme auf -1 result.
Am einfachsten (am wenigsten) wäre die Verwendung eines dynamischen Proxys:
%Vor%wo ThrowOnEOFProxy den Methodennamen überprüfen würde, rufen Sie es auf und wenn Ergebnis -1 ist, werfen Sie IOException ("EOF").
Tags und Links java sockets inputstream outputstream