在Java中将InputStream转换为字节数组

如何将整个InputStream读入字节数组?

您可以使用Apache Commons IO来处理这个和类似的任务。

IOUtilstypes有一个静态方法来读取一个InputStream并返回一个byte[]

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

在内部,这将创build一个ByteArrayOutputStream并将这些字节复制到输出,然后调用ByteArrayOutputStream toByteArray() 。 它通过复制4KiB块中的字节来处理大文件。

您需要从InputStream读取每个字节并将其写入ByteArrayOutputStream 。 然后你可以通过调用toByteArray()来检索底层字节数组。 例如

 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); } buffer.flush(); return buffer.toByteArray(); 

最后,二十年后,有了一个简单的解决scheme,无需第三方库,这要归功于Java 9 :

 InputStream is; … byte[] array = is.readAllBytes(); 

请注意便捷方法readNBytes(byte[] b, int off, int len)transferTo(OutputStream)寻址重复需要。

如果您碰巧使用谷歌番石榴 ,它将如此简单:

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

使用香草Java的DataInputStream和它的readFully方法(至less存在Java 1.4):

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

这种方法还有一些其他的方法,但我一直使用这个用例。

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

你真的需要图像作为一个byte[] ? 你究竟期待在byte[] – 图像文件的完整内容,以图像文件的任何格式编码,还是RGB像素值?

在这里的其他答案告诉你如何读取文件到一个byte[] 。 您的byte[]将包含文件的确切内容,您需要解码该文件以对图像数据执行任何操作。

用于读取(和写入)图像的Java标准API是ImageIO API,您可以在包javax.imageiofind它。 只需一行代码即可从文件中读取图像:

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

这会给你一个BufferedImage ,而不是一个byte[] 。 要获取图像数据,可以调用BufferedImage上的getRaster() 。 这会给你一个Raster对象,它具有访问像素数据的方法(它有几个getPixel() / getPixels()方法)。

查找javax.imageio.ImageIOjava.awt.image.BufferedImagejava.awt.image.Raster等的API文档

ImageIO默认支持多种图像格式:JPEG,PNG,BMP,WBMP和GIF。 可以添加对更多格式的支持(您需要一个实现ImageIO服务提供者接口的插件)。

另请参阅以下教程: 使用图像

如果您不想使用Apache commons-io库,则此代码段取自sun.misc.IOUtils类。 它比使用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; } 

与往常一样, Spring框架 (从3.2.2开始的spring-core)也适合你: StreamUtils.copyToByteArray()

@Adamski:你完全可以避免使用缓冲区。

http://www.exampledepot.com/egs/java.io/File2ByteArray.html复制的代码(是的,它非常详细,但是需要其他解决scheme的一半大小的内存。);

 // 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; } 
 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(); 

如果有人仍然在寻找一个没有依赖的解决scheme&& 如果你有一个文件

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); 

我知道这太迟了,但在这里我认为是更清晰的解决scheme,更可读…

 /** * 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(); } 

我试图编辑@ numan的答案与编写垃圾数据的修复,但编辑被拒绝。 虽然这段简短的代码是没有什么辉煌的,我看不到任何其他更好的答案。 以下是对我最有意义的事情:

 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(); 

顺便说一句ByteArrayOutputStream不需要closures。 为了可读性,尝试/最终构造被省略

请参阅InputStream.available()文档:

意识到您不能使用此方法调整容器的大小并假定您可以读取整个stream而不需要调整容器的大小,这一点尤其重要。 这样的调用者可能应该把他们读的所有东西写到一个ByteArrayOutputStream中,并把它转换成一个字节数组。 或者,如果你正在从一个文件读取,File.length返回文件的当前长度(尽pipe假设文件的长度不能改变可能是不正确的,读取文件本质上是活泼的)。

我用这个

 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(); } } 

这是我的复制粘贴版本:

 @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(); } 

Java 7及更高版本:

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

Java 9会给你一个不错的方法:

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

Java 8的方式(感谢BufferedReader和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>); } } 

请注意 ,此解决scheme抹除回车 ('\ r'),可能不合适。

这是一个优化的版本,尽量避免复制数据字节:

 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; }} 

如果使用ByteArrayOutputStream,你正在做一个额外的副本。 如果您在开始阅读之前知道stream的长度(例如InputStream实际上是一个FileInputStream,并且您可以在文件上调用file.length(),或者InputStream是一个Zipfile条目InputStream,则可以调用zipEntry。 length()),那么直接写入byte []数组会更好 – 它使用了一半的内存,并节省了时间。

 // 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); 

注意,如果需要处理这种可能性,上面最后一行处理的是在读取stream时被截断的文件,但是如果在读取stream时文件变得更长 ,byte []数组中的内容将不会被延长要包含新的文件内容,数组将简单地截断为旧的inputStreamLength

你可以尝试Cactoos :

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

下面的代码

 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(); } 

要么

 BufferedImage img = ... ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); ImageIO.write(img, "jpeg", baos); baos.flush(); byte[] result = baos.toByteArray(); baos.close(); 
 /*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(); } 

另一种情况是在向服务器发送请求并等待响应之后,通过stream获取正确的字节数组。

 /** * 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); 

这对我有用,

 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; } 

如果出于某种原因,将其包装在DataInputStream中,只需使用read来锤击它,直到它为您提供-1或您要求的整个块。

 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; }