¿Debo cerrar FileOutputStream, que está cubierto por PrintStream?

Estoy usando FileOutputStream con PrintStream de esta manera:

class PrintStreamDemo { public static void main(String args[]){ FileOutputStream out; PrintStream ps; // declare a print stream object try { // Create a new file output stream out = new FileOutputStream("myfile.txt"); // Connect print stream to the output stream ps = new PrintStream(out); ps.println ("This data is written to a file:"); System.err.println ("Write successfully"); ps.close(); } catch (Exception e){ System.err.println ("Error in writing to file"); } } } 

Estoy cerrando sólo el PrintStream. ¿Necesito cerrar también el FileOutputStream ( out.close(); )?

No, solo necesitas cerrar el flujo más externo. Se delegará todo el camino a las streams envueltas.

Sin embargo, su código contiene una falla conceptual, el cierre debería ocurrir finally , de lo contrario nunca se cerrará cuando el código arroje una excepción entre la apertura y el cierre.

P.ej

 public static void main(String args[]) throws IOException { PrintStream ps = null; try { ps = new PrintStream(new FileOutputStream("myfile.txt")); ps.println("This data is written to a file:"); System.out.println("Write successfully"); } catch (IOException e) { System.err.println("Error in writing to file"); throw e; } finally { if (ps != null) ps.close(); } } 

(tenga en cuenta que modifiqué el código para lanzar la excepción de modo que usted comprenda el motivo del problema, la excepción contiene información detallada sobre la causa del problema)

O bien, cuando ya está en Java 7, también puede hacer uso de ARM (Administración automática de recursos; también conocida como try-with-resources ) para que no necesite cerrar nada por sí mismo:

 public static void main(String args[]) throws IOException { try (PrintStream ps = new PrintStream(new FileOutputStream("myfile.txt"))) { ps.println("This data is written to a file:"); System.out.println("Write successfully"); } catch (IOException e) { System.err.println("Error in writing to file"); throw e; } } 

No, aquí está la implementación del PrintStream close() de PrintStream :

 public void close() { synchronized (this) { if (! closing) { closing = true; try { textOut.close(); out.close(); } catch (IOException x) { trouble = true; } textOut = null; charOut = null; out = null; } } 

Puedes ver out.close(); que cierra el flujo de salida.

No, no es necesario. El método PrintStream.close cierra automáticamente la secuencia de salida del subrayado.

Compruebe la API.

http://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html#close%28%29

No, según el javadoc, el método close cerrará la transmisión subyacente por ti.