2016-03-21 8 views
0

Ich habe immer gelernt, immer einen Stream zu schließen, wenn ich damit fertig bin. Java 7 gibt Ihnen eine neue Möglichkeit, dies zu tun (nämlich: try-with-resources), und alles ist in Ordnung, außer dass, wenn ich die OutputStream eines Sockets schließe, der Socket ebenfalls geschlossen wird. Dies ist kontraproduktiv, da ich Sockets in einer Streaming-Anwendung verwende.Java Socket schließend OutputStream

Also, wenn ich den Code unten ausführen, ich verstehe die ObjectOutputStream wird nach dem Try-Block geschlossen und die OutputStream der Buchse wird auch geschlossen, was schließlich führt meinen Sockel zu schließen.

try(ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) { 
    oos.writeObject(new MyDTO(data)); 
} 

Ich könnte natürlich meinen Code ändern, wie unten zu sehen, aber jeder hat mir immer gesagt, soll ich meinen Streams schließen, wenn ich sich mehr verwenden. Und das ist nur eine Methode, aber ich habe mehrere andere Methoden, die auch die OutputStream und ObjectOutputStream verwenden, um Daten an meine Client (s) zu senden.

try { 
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()) 
    oos.writeObject(new MyDTO(data)); 
} 

Muss ich andere Fehler und Fehlverhalten als Folge zu erwarten haben, nicht die ObjectOutputStream schließen? Ich denke, es ist schön, dass der Socket geschlossen ist, wenn Sie Anwendungen mit stoßweise Verkehr haben, aber es ist irgendwie komisch, wenn Sie eine Streaming-Anwendung machen.

Was ist die beste Praxis? Bring es mir bitte bei.

Antwort

1

Offensichtlich, wenn Sie noch die Ressourcen benötigen, werden Sie sie nicht schließen. Die Idee ist, sie zu schließen nach Sie sind fertig mit ihnen. Wenn Sie eine Chat-Software erstellen, behalten Sie die Verbindung und die verwendeten Ressourcen offen. Wenn Sie jedoch eine FTP-Software eines armen Mannes erstellen möchten, möchten Sie möglicherweise die Verbindung schließen, nachdem die Datei übertragen wurde.

Die try-with-resources soll es einfacher machen, Code zu schreiben, der garantiert seine Ressourcen freigibt, was oft nützlich ist, wenn es um Streams, Datenbankverbindungen und andere solche Dinge geht. Sie haben keine , um es überall zu verwenden, besonders wenn es Ihre Arbeit härter macht.

+0

Vielen Dank für Ihre Eingabe. Meine Frage war mehr, wenn es irgendwelche Probleme geben könnte, wenn ich den OutputStream wiederverwende und es mit mehr als einem ObjectOutputStream verwende. Die ObjectOutputStreams werden korrekt finalisiert/haben keinen Einfluss auf den Socket, nachdem ich ihren Bereich verlassen habe (d. H. Den try-Block)? –

+1

Auch wenn es funktioniert hat, ist es nicht schlau, einen Stream zu schließen, den du noch nicht benutzt hast. Es ist nur unnötige Arbeit von Ihrer Seite. – Kayaman

1

Die Frage ergibt keinen Sinn. Sie können nicht in der Praxis mehrere ObjectOutputStreams über den gleichen Socket erstellen (und selbst wenn Sie wissen, wie es geht, gibt es keinen Vorteil), so gibt es keinen Grund, Try-with-Ressourcen mit der ObjectOutputStream in erster Linie zu verwenden. Es sollte zusammen mit dem Socket erstellt werden, fast sicher als Instanzmitglied irgendwo gespeichert, und geschlossen, wenn Sie mit der Verbindung fertig sind.

+0

Wie gesagt, ich habe immer gelernt, meine Streams zu schließen. Du würdest also empfehlen, dass ich einen OutputStream zusammen mit meinem Socket erzeuge und es als Instanz in meinem Controller habe? Weil ich jetzt jedes Mal, wenn meine Methode (n) aufgerufen wird, einen Output/Input-Stream erzeuge. –

+0

Dann hast du auswendig gelernt, anstatt Intelligenz anzuwenden. Wenn Sie das hier beschriebene Muster der Verwendung eines Instanzmitglieds für die Streams angewendet hätten, wären Sie - * nicht * - in diese Falle geraten. Ich sehe keine Notwendigkeit, meine Antwort * wörtlich * zu wiederholen, was alles ist, wonach Sie zu fragen scheinen. – EJP

+0

Ja, aber wenn ich einen Server mit vielen Verbindungen habe, sind alle in einer Sammlung gespeichert.Ich müsste eine andere Sammlung des ObjectOutputStream zuordnen? Aus diesem Grund habe ich nie die Möglichkeit untersucht, ObjectOutputStreams instanziiert zu haben, und ich habe die Just-in-Time-Instanziierung als lokale Variable gewählt, wenn die Methode aufgerufen wird. –