2012-06-04 13 views
8

¿Cómo puedo crear una clase que tenga una implementación de OutputStream y escribirle el contenido?Cómo escribir cadenas en un OutputStream

Por ejemplo, el siguiente método de impresión es incorrecto y no se compilará. ¿Cuáles son las opciones o mejores técnicas?

public class FooBarPrinter{ 
    private OutputStream o; 
    public FooBarPrinter(OutputStream o){ 
     this.o=o; 
    } 

    public void print(String s){   
     o.write(s); 
    } 
} 
+6

Debería 1) mira la API de OutputStream y usa los métodos disponibles, y 2) si tienes un error, publica el error aquí para que no tengamos que adivinar cuál es el problema. –

+4

Por ejemplo, la API le mostrará que no hay un método OutputStream llamado write (...) que tome un parámetro String, por lo que no puede crear uno y esperar que funcione. En su lugar, debe usar los métodos disponibles. –

Respuesta

20

Un genérico OutputStream no tiene la capacidad de escribir una String directamente a él. En su lugar, debe obtener el byte[] del String y luego escribirlos en la transmisión.

public void print(String s){ 
    o.write(s.getBytes()); 
} 

consulte la documentación OutputStream java para más información sobre los tipos de datos de escritura soportados.

Mi sugerencia para mejorar esto es asegurarse de que el OutputStream que proporciona en el constructor es un BufferedOutputStream, ya que esto mejorará el rendimiento de su código. Funciona almacenando en el búfer algunos de los datos en la memoria, y escribiéndolos en el disco en grandes fragmentos en lugar de muchas escrituras más pequeñas.

Aquí está la documentación de Java para BufferedOutputStream

0

para escribir cadenas, echar un vistazo a la clase PrintStream. Puede ver un ejemplo de una clase que hace lo que pretende here.

Además, se puede envolver un OutputStream usando one of the PrintStream constructors:

public class FooBarPrinter{ 
    private PrintStream p; 
    public FooBarPrinter(OutputStream o){ 
    p = new PrintStream(o); 
    } 
    public void print(String s){  
    p.print(s); 
    } 
} 

EDITAR: en cuenta que también puede utilizar la clase PrintWriter de la misma manera como PrintStream arriba; que generalmente es mejor porque puede especificar la codificación que se va a usar, evitando cualquier dependencia de la plataforma.

+2

Se debe tener en cuenta que un 'PrintStream' maneja las excepciones de manera diferente: *" A diferencia de otras secuencias de salida, un 'PrintStream' nunca arroja una' IOException'; en cambio, las situaciones excepcionales simplemente establecen un indicador interno que se puede probar mediante el 'checkError () 'método." * –

+0

@GregKopff: Sí, ahora se nota. ¡Gracias! –

9

Creo que a las otras respuestas les falta un punto/pregunta importante.

¿Realmente debería utilizar un OutputStream?

Las jerarquías de clase OutputStream y InputStream son para escribir y leer datos orientados a bytes. Pero Java Strings no está orientado a bytes. Están orientados a caracteres (en una primera aproximación) y los caracteres en Java son unidades de código Unicode de 16 bits.

Cuando escribe caracteres en una secuencia de bytes, la JVM tiene que hacer una conversión a codificar los caracteres como bytes. De hecho, hay muchas maneras posibles de hacer esto. Por ejemplo, UTF-8 codificará cada carácter en la secuencia como uno o más bytes, Latin-1 o ASCII codificará un subconjunto de caracteres como bytes únicos y convertirá a otros en (probablemente) signos de interrogación. Y así.

Ahora bien, es posible escribir algo como esto:

public void print(String s){ 
     o.write(s.getBytes()); 
    } 

pero tiene un problema.El problema es que el método getBytes() en un String usa el esquema de codificación de caracteres predeterminado de la JVM para realizar la conversión. Y esto (el esquema de codificación predeterminado) depende del entorno en el que se lanzó la JVM. Entonces ese código, hace cosas diferentes dependiendo del entorno. Ahora usted podría arreglar eso especificando el juego de caracteres:

public void print(String s){ 
     o.write(s.getBytes("UTF-8")); 
    } 

pero que consigue engorroso si llama getBytes en muchos lugares.

Si está realizando una gran cantidad de salida basada en texto, una mejor idea es utilizar la API Writer en lugar de la API OutputStream. La API Writer y sus implementaciones se ocupan de la conversión bajo el capó ... y de manera más consistente y eficiente.

El punto final es que hay otras API que pueden ser útiles para realizar salidas basadas en texto.

  • El BufferedWriter clase (y también BufferedOutputStream) soporte de salida eficiente mediante la introducción de almacenamiento en búfer en memoria en el proceso de salida. Esto ahorra llamadas al sistema, especialmente si está realizando muchas pequeñas operaciones de escritura.
  • La clase PrintWriter proporciona una gran cantidad de métodos prácticos y también elimina la necesidad de manejar IOExceptions. (Si ocurre una IOException, el PrintWriter lo anota. Hay un método para probar si se ha producido una excepción. Esto puede ser útil o peligroso, dependiendo de lo que esté haciendo ...)
Cuestiones relacionadas