streamsource from example create convertir convert java string inputstream

from - ¿Cómo puedo obtener un java.io.InputStream de un java.lang.String?



inputstreamreader to inputstream java (8)

Tengo un String que quiero usar como InputStream . En Java 1.0, puede usar java.io.StringBufferInputStream , pero eso ha sido @Deprecrated (por una buena razón: no puede especificar la codificación del juego de caracteres):

Esta clase no convierte correctamente los caracteres en bytes. A partir de JDK 1.1, la forma preferida de crear una secuencia a partir de una cadena es a través de la clase StringReader .

Puede crear un java.io.Reader con java.io.StringReader , pero no hay adaptadores para tomar un Reader y crear un InputStream .

Encontré un error antiguo que pedía un reemplazo adecuado, pero no existe tal cosa, por lo que puedo decir.

La solución sugerida frecuentemente es usar java.lang.String.getBytes() como entrada para java.io.ByteArrayInputStream :

public InputStream createInputStream(String s, String charset) throws java.io.UnsupportedEncodingException { return new ByteArrayInputStream(s.getBytes(charset)); }

pero eso significa materializar toda la String en la memoria como una matriz de bytes, y anula el propósito de una secuencia. En la mayoría de los casos, esto no es gran cosa, pero estaba buscando algo que preservara la intención de una transmisión: que la menor cantidad posible de datos se (re) materialice en la memoria.


Bueno, una forma posible es:

Por supuesto, esto parece una forma bastante hackosa de hacerlo, pero al menos es una manera.


En mi opinión, la manera más fácil de hacerlo es presionando los datos a través de un escritor:

public class StringEmitter { public static void main(String[] args) throws IOException { class DataHandler extends OutputStream { @Override public void write(final int b) throws IOException { write(new byte[] { (byte) b }); } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } @Override public void write(byte[] b, int off, int len) throws IOException { System.out.println("bytecount=" + len); } } StringBuilder sample = new StringBuilder(); while (sample.length() < 100 * 1000) { sample.append("sample"); } Writer writer = new OutputStreamWriter( new DataHandler(), "UTF-16"); writer.write(sample.toString()); writer.close(); } }

La implementación de JVM que estoy utilizando empujó los datos a través de fragmentos de 8K, pero podría tener algún efecto en el tamaño del búfer reduciendo el número de caracteres escritos a la vez y llamando al color.

Una alternativa a escribir su propio envoltorio CharsetEncoder para usar un Escritor para codificar los datos, aunque es algo doloroso hacer lo correcto. Esta debería ser una implementación confiable (si ineficiente):

/** Inefficient string stream implementation */ public class StringInputStream extends InputStream { /* # of characters to buffer - must be >=2 to handle surrogate pairs */ private static final int CHAR_CAP = 8; private final Queue<Byte> buffer = new LinkedList<Byte>(); private final Writer encoder; private final String data; private int index; public StringInputStream(String sequence, Charset charset) { data = sequence; encoder = new OutputStreamWriter( new OutputStreamBuffer(), charset); } private int buffer() throws IOException { if (index >= data.length()) { return -1; } int rlen = index + CHAR_CAP; if (rlen > data.length()) { rlen = data.length(); } for (; index < rlen; index++) { char ch = data.charAt(index); encoder.append(ch); // ensure data enters buffer encoder.flush(); } if (index >= data.length()) { encoder.close(); } return buffer.size(); } @Override public int read() throws IOException { if (buffer.size() == 0) { int r = buffer(); if (r == -1) { return -1; } } return 0xFF & buffer.remove(); } private class OutputStreamBuffer extends OutputStream { @Override public void write(int i) throws IOException { byte b = (byte) i; buffer.add(b); } } }


Hay un adaptador de Apache Commons-IO que se adapta de Reader a InputStream, que se llama ReaderInputStream .

Código de ejemplo:

@Test public void testReaderInputStream() throws IOException { InputStream inputStream = new ReaderInputStream(new StringReader("largeString"), StandardCharsets.UTF_8); Assert.assertEquals("largeString", IOUtils.toString(inputStream, StandardCharsets.UTF_8)); }

Referencia: https://.com/a/27909221/5658642


Puede tomar la ayuda de la biblioteca org.hsqldb.lib.

public StringInputStream(String paramString) { this.str = paramString; this.available = (paramString.length() * 2); }


Sé que esta es una vieja pregunta, pero tuve el mismo problema hoy, y esta fue mi solución:

public static InputStream getStream(final CharSequence charSequence) { return new InputStream() { int index = 0; int length = charSequence.length(); @Override public int read() throws IOException { return index>=length ? -1 : charSequence.charAt(index++); } }; }



Una solución es java.nio.charset.CharsetEncoder suya, creando una implementación de InputStream que probablemente usaría java.nio.charset.CharsetEncoder para codificar cada char o fragmento de char a una matriz de bytes para el InputStream según sea necesario.


Actualización: esta respuesta es precisamente lo que el OP no quiere. Por favor, lea las otras respuestas.

Para aquellos casos en los que no nos importa que los datos se vuelvan a materializar en la memoria, use:

new ByteArrayInputStream(str.getBytes("UTF-8"))