Java Detect geschlossener Stream

8

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:

  • Kann ich sicher annehmen, dass -1 nur ist? zurückgegeben, wenn der Stream geschlossen ist?
  • Gibt es keine Möglichkeit, das IO neu zu erstellen? Ausnahme, die auftritt, wenn der Verbindung wird gewaltsam unterbrochen?
  • Soll ich ein Paket senden, das meinem InputStream sagt, dass es statt der beiden vorherigen Methoden schließen soll?

Danke!

    
Derek 10.04.2011, 02:06
quelle

5 Antworten

6

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.

    
WhiteFang34 10.04.2011, 02:10
quelle
2
  

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.

    
Stephen C 10.04.2011 02:30
quelle
0

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.

    
z7sg Ѫ 10.04.2011 02:12
quelle
0

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.

    
Edwin Dalorzo 10.04.2011 02:22
quelle
-1
  

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").

    
Vladimir Dyuzhev 10.04.2011 02:24
quelle