readfully ioutils array java bytearray inputstream

ioutils - Convertir InputStream a matriz de bytes en Java



inputstream to string (30)

¿Realmente necesitas la imagen como un byte[] ? ¿Qué espera exactamente en el byte[] : el contenido completo de un archivo de imagen, codificado en el formato en que se encuentre el archivo de imagen, o los valores de píxeles RGB?

Otras respuestas aquí le muestran cómo leer un archivo en un byte[] . Su byte[] contendrá el contenido exacto del archivo, y tendrá que decodificarlo para hacer cualquier cosa con los datos de la imagen.

La API estándar de Java para leer (y escribir) imágenes es la API de ImageIO, que puede encontrar en el paquete javax.imageio . Puede leer una imagen de un archivo con una sola línea de código:

BufferedImage image = ImageIO.read(new File("image.jpg"));

Esto le dará una imagen BufferedImage , no un byte[] . Para obtener los datos de la imagen, puede llamar a getRaster() en BufferedImage . Esto le dará un objeto Raster , que tiene métodos para acceder a los datos de píxeles (tiene varios métodos getPixel() / getPixels() ).

javax.imageio.ImageIO documentación de la API para javax.imageio.ImageIO , java.awt.image.BufferedImage , java.awt.image.Raster , etc.

ImageIO admite una serie de formatos de imagen por defecto: JPEG, PNG, BMP, WBMP y GIF. Es posible agregar soporte para más formatos (necesitaría un complemento que implemente la interfaz del proveedor de servicios ImageIO).

Véase también el siguiente tutorial: Trabajar con imágenes

¿Cómo leo un InputStream completo en una matriz de bytes?


@Adamski: Puedes evitar el buffer por completo.

Código copiado de http://www.exampledepot.com/egs/java.io/File2ByteArray.html (Sí, es muy detallado, pero necesita la mitad del tamaño de la memoria que la otra solución).

// Returns the contents of the file in a byte array. public static byte[] getBytesFromFile(File file) throws IOException { InputStream is = new FileInputStream(file); // Get the size of the file long length = file.length(); // You cannot create an array using a long type. // It needs to be an int type. // Before converting to an int type, check // to ensure that file is not larger than Integer.MAX_VALUE. if (length > Integer.MAX_VALUE) { // File is too large } // Create the byte array to hold the data byte[] bytes = new byte[(int)length]; // Read in the bytes int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read in if (offset < bytes.length) { throw new IOException("Could not completely read file "+file.getName()); } // Close the input stream and return bytes is.close(); return bytes; }


Aquí hay una versión optimizada, que intenta evitar copiar los bytes de datos tanto como sea posible:

private static byte[] loadStream (InputStream stream) throws IOException { int available = stream.available(); int expectedSize = available > 0 ? available : -1; return loadStream(stream, expectedSize); } private static byte[] loadStream (InputStream stream, int expectedSize) throws IOException { int basicBufferSize = 0x4000; int initialBufferSize = (expectedSize >= 0) ? expectedSize : basicBufferSize; byte[] buf = new byte[initialBufferSize]; int pos = 0; while (true) { if (pos == buf.length) { int readAhead = -1; if (pos == expectedSize) { readAhead = stream.read(); // test whether EOF is at expectedSize if (readAhead == -1) { return buf; } } int newBufferSize = Math.max(2 * buf.length, basicBufferSize); buf = Arrays.copyOf(buf, newBufferSize); if (readAhead != -1) { buf[pos++] = (byte)readAhead; } } int len = stream.read(buf, pos, buf.length - pos); if (len < 0) { return Arrays.copyOf(buf, pos); } pos += len; } }


Como siempre, también Spring Framework (spring-core desde 3.2.2) tiene algo para ti: StreamUtils.copyToByteArray()


Consulte la documentación de InputStream.available() :

Es particularmente importante darse cuenta de que no debe usar este método para dimensionar un contenedor y suponer que puede leer la totalidad de la secuencia sin necesidad de cambiar el tamaño del contenedor. Dichos llamadores probablemente deberían escribir todo lo que leen en un ByteArrayOutputStream y convertirlo en una matriz de bytes. Alternativamente, si está leyendo un archivo, File.length devuelve la longitud actual del archivo (aunque suponiendo que la longitud del archivo no puede cambiar puede ser incorrecta, leer un archivo es intrínsecamente imprudente).


Debajo de los codigos

public static byte[] serializeObj(Object obj) throws IOException { ByteArrayOutputStream baOStream = new ByteArrayOutputStream(); ObjectOutputStream objOStream = new ObjectOutputStream(baOStream); objOStream.writeObject(obj); objOStream.flush(); objOStream.close(); return baOStream.toByteArray(); }

O

BufferedImage img = ... ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); ImageIO.write(img, "jpeg", baos); baos.flush(); byte[] result = baos.toByteArray(); baos.close();


Debe leer cada byte de su InputStream y escribirlo en un ByteArrayOutputStream . Luego puede recuperar la matriz de bytes subyacente llamando a toByteArray() ; p.ej

InputStream is = ... ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[16384]; while ((nRead = is.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } return buffer.toByteArray();


El otro caso para obtener la matriz de bytes correcta a través de la transmisión, después de enviar la solicitud al servidor y esperar la respuesta.

/** * Begin setup TCP connection to PC app * to open integrate connection between mobile app and pc app (or mobile app) */ mSocket = new Socket(IP, port); // mSocket.setSoTimeout(30000); DataOutputStream mDos = new DataOutputStream(mSocket.getOutputStream()); String str = "MobileRequest#" + params[0] + "#<EOF>"; mDos.write(str.getBytes()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } /* Since data are accepted as byte, all of them will be collected in the following byte array which initialised with accepted data length. */ DataInputStream mDis = new DataInputStream(mSocket.getInputStream()); byte[] data = new byte[mDis.available()]; // Collecting data into byte array for (int i = 0; i < data.length; i++) data[i] = mDis.readByte(); // Converting collected data in byte array into String. String RESPONSE = new String(data);


En caso de que alguien todavía esté buscando una solución sin una dependencia y si tiene un archivo .

1) DataInputStream

byte[] data = new byte[(int) file.length()]; DataInputStream dis = new DataInputStream(new FileInputStream(file)); dis.readFully(data); dis.close();

2) ByteArrayOutputStream

InputStream is = new FileInputStream(file); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[(int) file.length()]; while ((nRead = is.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); }

3) RandomAccessFile

RandomAccessFile raf = new RandomAccessFile(file, "r"); byte[] data = new byte[(int) raf.length()]; raf.readFully(data);


Envuélvalo en un DataInputStream si eso está fuera de la mesa por alguna razón, solo use leer para marcarlo hasta que le dé un -1 o todo el bloque que solicitó.

public int readFully(InputStream in, byte[] data) throws IOException { int offset = 0; int bytesRead; boolean read = false; while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) { read = true; offset += bytesRead; if (offset >= data.length) { break; } } return (read) ? offset : -1; }


Estás haciendo una copia adicional si usas ByteArrayOutputStream. Si conoce la longitud del flujo antes de comenzar a leerlo (por ejemplo, InputStream es en realidad un FileInputStream y puede llamar a file.length () en el archivo, o InputStream es una entrada de archivo zip InputStream y puede llamar a zipEntry. length ()), entonces es mucho mejor escribir directamente en la matriz de bytes []: usa la mitad de la memoria y ahorra tiempo.

// Read the file contents into a byte[] array byte[] buf = new byte[inputStreamLength]; int bytesRead = Math.max(0, inputStream.read(buf)); // If needed: for safety, truncate the array if the file may somehow get // truncated during the read operation byte[] contents = bytesRead == inputStreamLength ? buf : Arrays.copyOf(buf, bytesRead);

NB: la última línea anterior trata sobre los archivos truncados mientras se lee la secuencia, si necesita manejar esa posibilidad, pero si el archivo se alarga mientras se lee la secuencia, el contenido de la matriz byte [] no se alargará para incluir el nuevo contenido del archivo, la matriz simplemente se truncará a la longitud antigua inputStreamLength .


Esta es mi versión de copiar y pegar:

@SuppressWarnings("empty-statement") public static byte[] inputStreamToByte(InputStream is) throws IOException { if (is == null) { return null; } // Define a size if you have an idea of it. ByteArrayOutputStream r = new ByteArrayOutputStream(2048); byte[] read = new byte[512]; // Your buffer size. for (int i; -1 != (i = is.read(read)); r.write(read, 0, i)); is.close(); return r.toByteArray(); }


Estamos viendo un poco de retraso por pocas transacciones de AWS, mientras que convertimos el objeto S3 a ByteArray.

Nota: S3 Object es un documento PDF (el tamaño máximo es de 3 mb).

Estamos utilizando la opción # 1 (org.apache.commons.io.IOUtils) para convertir el objeto S3 a ByteArray. Hemos notado que S3 proporciona el método IOUtils incorporado para convertir el objeto S3 a ByteArray, le solicitamos que confirme cuál es la mejor manera de convertir el objeto S3 a ByteArray para evitar el retraso.

Opción 1:

import org.apache.commons.io.IOUtils; is = s3object.getObjectContent(); content =IOUtils.toByteArray(is);

Opcion 2:

import com.amazonaws.util.IOUtils; is = s3object.getObjectContent(); content =IOUtils.toByteArray(is);

También avíseme si tenemos otra forma mejor de convertir el objeto s3 a bytearray



Intenté editar la respuesta de @ numan con una solución para escribir datos de basura, pero la edición fue rechazada. Si bien este pequeño código no tiene nada de brillante, no veo otra respuesta mejor. Esto es lo que tiene más sentido para mí:

ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; // you can configure the buffer size int length; while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length); //copy streams in.close(); // call this in a finally block byte[] result = out.toByteArray();

Por cierto, no es necesario cerrar ByteArrayOutputStream. Intento / finalmente construcciones omitidas para facilitar la lectura.


Java 7 y posteriores:

import sun.misc.IOUtils; ... InputStream in = ...; byte[] buf = IOUtils.readFully(in, -1, false);


Java 8 way (gracias a BufferedReader y Adam Bien )

private static byte[] readFully(InputStream input) throws IOException { try (BufferedReader buffer = new BufferedReader(new InputStreamReader(input))) { return buffer.lines().collect(Collectors.joining("/n")).getBytes(<charset_can_be_specified>); } }

Tenga en cuenta que esta solución borra el retorno de carro (''/ r'') y puede ser inapropiada.


Java 9 te dará finalmente un buen método:

InputStream in = ...; ByteArrayOutputStream bos = new ByteArrayOutputStream(); in.transferTo( bos ); byte[] bytes = bos.toByteArray();


Puede usar Apache Commons IO para manejar esta y otras tareas similares.

El tipo IOUtils tiene un método estático para leer un InputStream y devolver un byte[] .

InputStream is; byte[] bytes = IOUtils.toByteArray(is);

Internamente, esto crea un ByteArrayOutputStream y copia los bytes a la salida, luego llama a toByteArray() . Maneja archivos grandes copiando los bytes en bloques de 4KiB.


Puedes probar Cactoos :

byte[] array = new BytesOf(stream).bytes();


Sé que es demasiado tarde, pero aquí creo que es una solución más limpia y más legible ...

/** * method converts {@link InputStream} Object into byte[] array. * * @param stream the {@link InputStream} Object. * @return the byte[] array representation of received {@link InputStream} Object. * @throws IOException if an error occurs. */ public static byte[] streamToByteArray(InputStream stream) throws IOException { byte[] buffer = new byte[1024]; ByteArrayOutputStream os = new ByteArrayOutputStream(); int line = 0; // read bytes from stream, and store them in buffer while ((line = stream.read(buffer)) != -1) { // Writes bytes from byte array (buffer) into output stream. os.write(buffer, 0, line); } stream.close(); os.flush(); os.close(); return os.toByteArray(); }


Si no desea utilizar la biblioteca de Apache commons-io, este fragmento de código se toma de la clase sun.misc.IOUtils. Es casi el doble de rápido que la implementación común utilizando ByteBuffers:

public static byte[] readFully(InputStream is, int length, boolean readAll) throws IOException { byte[] output = {}; if (length == -1) length = Integer.MAX_VALUE; int pos = 0; while (pos < length) { int bytesToRead; if (pos >= output.length) { // Only expand when there''s no room bytesToRead = Math.min(length - pos, output.length + 1024); if (output.length < pos + bytesToRead) { output = Arrays.copyOf(output, pos + bytesToRead); } } else { bytesToRead = output.length - pos; } int cc = is.read(output, pos, bytesToRead); if (cc < 0) { if (readAll && length != Integer.MAX_VALUE) { throw new EOFException("Detect premature EOF"); } else { if (output.length != pos) { output = Arrays.copyOf(output, pos); } break; } } pos += cc; } return output; }


Si usas la guayaba de google , será tan simple como:

byte[] bytes = ByteStreams.toByteArray(inputStream);


Use DataInputStream de Java de vainilla y su método readFully (existe desde al menos Java 1.4):

... byte[] imgDataBa = new byte[(int)imgFile.length()]; DataInputStream dataIs = new DataInputStream(new FileInputStream(imgFile)); dataIs.readFully(imgDataBa); ...

Hay otros sabores de este método, pero lo uso todo el tiempo para este caso de uso.


Yo uso esto.

public static byte[] toByteArray(InputStream is) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); try { byte[] b = new byte[4096]; int n = 0; while ((n = is.read(b)) != -1) { output.write(b, 0, n); } return output.toByteArray(); } finally { output.close(); } }


Esto funciona para mi

if(inputStream != null){ ByteArrayOutputStream contentStream = readSourceContent(inputStream); String stringContent = contentStream.toString(); byte[] byteArr = encodeString(stringContent); }

readSourceContent ()

public static ByteArrayOutputStream readSourceContent(InputStream inputStream) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); int nextChar; try { while ((nextChar = inputStream.read()) != -1) { outputStream.write(nextChar); } outputStream.flush(); } catch (IOException e) { throw new IOException("Exception occurred while reading content", e); } return outputStream; }

encodeString ()

public static byte[] encodeString(String content) throws UnsupportedEncodingException { byte[] bytes; try { bytes = content.getBytes(); } catch (UnsupportedEncodingException e) { String msg = ENCODING + " is unsupported encoding type"; log.error(msg,e); throw new UnsupportedEncodingException(msg, e); } return bytes; }


/*InputStream class_InputStream = null; I am reading class from DB class_InputStream = rs.getBinaryStream(1); Your Input stream could be from any source */ int thisLine; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while ((thisLine = class_InputStream.read()) != -1) { bos.write(thisLine); } bos.flush(); byte [] yourBytes = bos.toByteArray(); /*Don''t forget in the finally block to close ByteArrayOutputStream & InputStream In my case the IS is from resultset so just closing the rs will do it*/ if (bos != null){ bos.close(); }


ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; while (true) { int r = in.read(buffer); if (r == -1) break; out.write(buffer, 0, r); } byte[] ret = out.toByteArray();


Input Stream is ... ByteArrayOutputStream bos = new ByteArrayOutputStream(); int next = in.read(); while (next > -1) { bos.write(next); next = in.read(); } bos.flush(); byte[] result = bos.toByteArray(); bos.close();


public static byte[] getBytesFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); byte[] buffer = new byte[0xFFFF]; for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { os.write(buffer, 0, len); } return os.toByteArray(); }