2008-10-19 14 views
469

¿Cuál es la mejor manera de canalizar la salida de un java.io.OutputStream a una cadena en Java?Obtener un OutputStream en una cadena

Decir que tengo el método:

writeToStream(Object o, OutputStream out) 

que escribe algunos datos del objeto en el flujo dado. Sin embargo, quiero obtener esta salida en una cadena lo más fácilmente posible.

Estoy pensando en escribir una clase como esta (no probado):

class StringOutputStream extends OutputStream { 

    StringBuilder mBuf; 

    public void write(int byte) throws IOException { 
    mBuf.append((char) byte); 
    } 

    public String getString() { 
    return mBuf.toString(); 
    } 
} 

Pero hay una manera mejor? ¡Solo quiero hacer una prueba!

+6

¿Tiene solamente bytes ASCII? ¿NO necesitas Codepage? – Horcrux7

+0

En este caso, sí.Sin embargo, buen punto, no lo había pensado. –

Respuesta

514

Yo usaría un ByteArrayOutputStream. Y en el acabado se puede llamar:

new String(baos.toByteArray(), codepage); 

o mejor

baos.toString(codepage); 

Para el constructor de String del codepage puede ser una cadena o una instancia de java.nio.charset.Charset. Un posible valor es java.nio.charset.StandardCharsets.UTF_8.

El método toString acepta solo un parámetro String as codepage (stand Java 8).

+7

ByteArrayOutputStream no tiene el método toArray(); sin embargo, tiene toByteArray(). ¿Puedes arreglar la respuesta? Además, ¿por qué no utilizar baos.toString (String charsetName) que sería un poco más simple. – Jonik

+0

Gracias por la sugerencia con toString (juego de caracteres). Nunca he visto el toString porque esperaba un ByteArrayOutputStream @ 123456. También he corregido el error con toByteArray(). – Horcrux7

+0

También tenga en cuenta que algunas páginas de códigos no están instaladas a menos que las solicite explícitamente con una instalación personalizada. –

40

Me gusta la biblioteca Apache Commons IO. Eche un vistazo a su versión de ByteArrayOutputStream, que tiene un método toString(String enc), así como toByteArray(). El uso de componentes existentes y confiables como el proyecto Commons permite que su código sea más pequeño y más fácil de extender y reutilizar. Buena suerte.

+8

Ahórrese un año de su vida y lea todas las API comunes para que cuando encuentre un problema, pueda desatar una solución completamente probada y propiedad de la comunidad. –

+14

Hmm, soy un ávido usuario de Apache Commons, pero en este caso no veo por qué debería usar ByteArrayOutputStream de Commons IO en lugar del propio java.io.ByteArrayOutputStream de JDK. Este último también proporciona los métodos String (String charsetName) y toByteArray(). ¿Cuidado para elaborar? – Jonik

+1

Sí, dado que el contexto original era una mejor manera de transmitir y extraer contenido, incluí el ejemplo de IO de Commons, ya que incluía un método 'write (InputStream)' para un mecanismo indefinido/cuestionable para poblar el OutputStream. Yo también iría con el JDK. –

11

Esto es lo que terminé haciendo:

Obj.writeToStream(toWrite, os); 
try { 
    String out = new String(os.toByteArray(), "UTF-8"); 
    assertTrue(out.contains("testString")); 
} catch (UnsupportedEncondingException e) { 
    fail("Caught exception: " + e.getMessage()); 
} 

Donde OS es una ByteArrayOutputStream.

+3

¿Qué es 'os' en tu código? – Synox

+1

@JavaJigs Aclaré esto en la parte inferior de mi respuesta hace casi 5 años :) –

+10

Considere reemplazar '' UTF-8 "' con 'StandardCharsets.UTF_8'. –

21

Esto funcionó muy bien

OutputStream output = new OutputStream() 
    { 
     private StringBuilder string = new StringBuilder(); 
     @Override 
     public void write(int b) throws IOException { 
      this.string.append((char) b); 
     } 

     //Netbeans IDE automatically overrides this toString() 
     public String toString(){ 
      return this.string.toString(); 
     } 
    }; 

método de llamada = >>marshaller.marshal((Object) toWrite , (OutputStream) output);

a continuación para imprimir la cadena o conseguirlo simplemente hacer referencia a la "salida" corriente misma A modo de ejemplo, para imprimir la cadena a cabo para consolar = >>System.out.println(output);

FYI: mi llamada de método marshaller.marshal(Object,Outputstream) es para trabajar con xml. Es irrelevante para este tema.

Esto es altamente derrochador para uso productivo, hay muchas conversiones y es un poco flojo. Esto fue codificado para demostrarle que es totalmente posible crear un OuputStream personalizado y generar una cadena. Pero solo usa Horcrux7 y todo está bien con solo dos llamadas a métodos.

Y el mundo vive en otro día ....

+7

Simplemente enviar un byte a char solo funcionará en ascii. Utilice ByteArrayOutputStream como Horcrux7 –

+2

De acuerdo con Dave Ray. No puede suponer que su byte es un carácter ASCII. Necesita interpretar los bytes usando una codificación. Utilice byteArrayOutputStream.toString ("UTF-8") o una nueva cadena (byteArrayOutputStream.toByteArray(), "UTF-8"). –

-11

¿Por qué no se utiliza un ByteArrayOutputStream? Eso es lo que se supone que debes usar para este propósito.

+51

¿Quieres decir como todas las otras respuestas que han estado aquí durante más de 4 años sugieren? ;) –

Cuestiones relacionadas