Hm. Was genau nun „brandgefährlich“ ist, hat sich mir nicht erschlossen. Aber ich finde (auch, falls du das meintest) dass einiges im Dunstkreis von streams unerfreulich vage ist:
- Bei den meisten stream-Wrappern wird bei einem
close
auch der „innere“ Stream geschlossen (aber wohl nicht bei allen) - Bei den meisten streams ist
close
idempotent (aber wohl nicht bei allen) - Bei den meisten streams wird bei einem
close
erst einflush
gemacht (aber vielleicht nicht bei allen…?) - Nebnbei: Auch ein normaler
java.util.Stream
hat einclose
, und bei manchen ist es nötig, das aufzurufen, aber wohl nicht bei allen…
(Da bin ich vor einer Weile drüber gestolpert, als ich für data die Möglichkeit bieten wollte, einzelne Zeilen einer CSV über einen Stream zu verarbeiten. Das blöde ist: Wenn man einen Stream
in die Hand gedrückt bekommt, weiß man nie, ob man ihn schließen muss. Man könnte meinen ~„joa, dann macht man halt was, dass er bei einer terminal operation geschlossen wird“, aber so einfach ist das alles nicht…)
Tatsächlich kann aber z.B. auch das explizite Schließen eines „eingewickelten“ Streams richtig eklig sein. Ganz grob (wirklich nur sinngemäß) bei so einem Muster:
void writeSomething(OutputStream outputStream) {
writeSomeXml(outputStream);
writeSomeJson(outputStream);
}
void writeSomeXml(OutputStream outputStream) {
try (XmlWriter w = new XmlWriter(outputStream)) { ... }
}
void writeSomeJson(OutputStream outputStream) {
try (JsonWriter w = new JsonWriter(outputStream)) { ... }
}
Wenn man mehrere Sachen hintereinander in einen Stream schreiben will, kann ein automatisches Schließen lästig sein. IIRC habe ich sogar mal was mit
class NonCloseableOutputStream implements OutputStream {
OutputStream delegate;
void write(byte data[]) { delegate.write(data);
void close() { /** delegate.close()? NO! */ }
}
gepfuscht, weil’s keine andere Lösung zu geben schien (gab es IIRC aber dann doch…).
EDIT: Ganz allgemein versuche ich aber immer, wenn ein InputStream
oder OutputStream
an eine Methode übergeben wird, klipp und klar dazuzuschreiben, ob…
/**
* ...
* The given stream will be closed when the operation is finished
*/
oder
/**
* ...
* The caller is responsible for closing the given stream
*/
Und nach Möglichkeit mache ich letzteres: Ein stream, der einmal zu ist, den kriegt man halt nicht mehr auf. (Lästig ist es dann, wenn irgendeine Library das erstens nicht macht, und zweitens die Bedingungen, unter denen etwas geschlossen wird, haarsträubend undurchsichtig sind … )