关于BytErRi:在爪哇中转换输入流到字节数组

Convert InputStream to byte array in Java

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


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

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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
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();


最后,二十年后,有一个简单的解决方案不需要第三方库A,由于Java  ;9:

1
2
3
InputStream is;

byte[] array = is.readAllBytes();

便利的方法和readNBytes(byte[] b, int off, int len)音符也不需要transferTo(OutputStream)寻址。


使用香草爪哇的EDOCX1 23和它的EDCOX1×24的方法(至少存在Java 1.4):

1
2
3
4
5
...
byte[] bytes = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(bytes);
...

这个方法还有其他一些风格,但是我一直在为这个用例使用它。


如果你碰巧使用Google Guava,它将简单到:

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


1
2
3
4
5
6
7
8
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();
}


一如既往的,所以(Spring Spring框架的核心。3.2.2):StreamUtils.copyToByteArray()安切洛蒂的东西。


你真的需要像byte[]那样的图像吗?在byte[]中,您期望图像文件的完整内容(以图像文件的任何格式或RGB像素值编码)是什么?

这里的其他答案向您展示了如何将文件读取到byte[]中。您的byte[]将包含文件的确切内容,您需要对其进行解码以处理图像数据。

Java的用于读取(和写入)图像的标准API是IMAIO API,可以在包EDOCX1 12中找到。只需一行代码就可以从文件中读取图像:

1
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服务提供程序接口的插件)。

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


如果您不想使用ApacheCommons IO库,那么这段代码取自sun.misc.ioutils类。它的速度几乎是使用bytebuffers的常见实现速度的两倍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
}


在案例解决方案是寻找一个安静的人,没有依赖性,如果你有一个文件。

1) DataInputStream

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

2) ByteArrayOutputStream

1
2
3
4
5
6
7
 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

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


1
2
3
4
5
6
7
8
9
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();

@阿达姆斯基:你可以完全避免缓冲。

从http://www.exampledepot.com/egs/java.io/file2bytearray.html复制的代码(是的,它非常冗长,但需要的内存大小是其他解决方案的一半。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 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;
}


1
2
3
4
5
6
7
8
9
10
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();


安全解决方案(有能力正确close流):

  • 9 +:Java版

    1
    2
    3
    4
    final byte[] bytes;
    try (inputStream) {
        bytes = inputStream.readAllBytes();
    }
  • 8:Java版

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public static byte[] readAllBytes(InputStream inputStream) throws IOException {
        final int bufLen = 4 * 0x400; // 4KB
        byte[] buf = new byte[bufLen];
        int readLen;
        IOException exception = null;

        try {
            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
                    outputStream.write(buf, 0, readLen);

                return outputStream.toByteArray();
            }
        } catch (IOException e) {
            exception = e;
            throw e;
        } finally {
            if (exception == null) inputStream.close();
            else try {
                inputStream.close();
            } catch (IOException e) {
                exception.addSuppressed(e);
            }
        }
    }
  • (9)当kotlin版Java不是访问):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Throws(IOException::class)
    fun InputStream.readAllBytes(): ByteArray {
        val bufLen = 4 * 0x400 // 4KB
        val buf = ByteArray(bufLen)
        var readLen: Int = 0

        ByteArrayOutputStream().use { o ->
            this.use { i ->
                while (i.read(buf, 0, bufLen).also { readLen = it } != -1)
                    o.write(buf, 0, readLen)
            }

            return o.toByteArray()
        }
    }

    为了避免在循环中use湖。


9你想给我们的Java的好方法:

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


我知道已经太迟了,但我认为这里是更清晰的解决方案,更具可读性…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * 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();
}


InputStream.available()文档:

It is particularly important to realize that you must not use this
method to size a container and assume that you can read the entirety
of the stream without needing to resize the container. Such callers
should probably write everything they read to a ByteArrayOutputStream
and convert that to a byte array. Alternatively, if you're reading
from a file, File.length returns the current length of the file
(though assuming the file's length can't change may be incorrect,
reading a file is inherently racy).


我试图编辑@numan的答案,并修复了写垃圾数据的问题,但编辑被拒绝了。虽然这段短代码并不出色,但我看不到其他更好的答案。以下是对我来说最有意义的:

1
2
3
4
5
6
7
8
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();

btw bytearrayOutputstream不需要关闭。为便于阅读,省略了try/finally结构


Java的方式(8 bufferedreader和感谢亚当Myint)

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

注意,这个解决方案wipes回车(R)和可以是不适当的。


Java 7和目标:

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


下面是一个优化版本,它尽量避免复制数据字节:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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,则需要做额外的复制。如果在开始读取流之前知道它的长度(例如,inputstream实际上是一个file inputstream,您可以对该文件调用file.length(),或者inputstream是一个zipfile条目inputstream,并且您可以调用zipEntry.length()),那么直接写入byte[]数组就更好了--它使用一半的内存,并保存时间。

1
2
3
4
5
6
7
8
// 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);

注意:上面最后一行处理在读取流时被截断的文件,如果您需要处理这种可能性,但是如果在读取流时文件变长,那么byte[]数组中的内容将不会被加长以包含新的文件内容,那么数组将被截断为旧的inputstreamleng长度。钍。


我用这个。

1
2
3
4
5
6
7
8
9
10
11
12
13
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();
        }
    }


这是我的版本:复制粘贴

1
2
3
4
5
6
7
8
9
10
11
12
@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();
}


如果把它包在一个输入流和关闭非台,只是使用它,直到它读取到锤给你1块或整个你所寻求的。

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

你可以尝试cactoos:

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

我们看到一些延迟时间转换为自动交易,而一个ByteArray S3对象。

注:S3对象是PDF文档(最大尺寸是3 MB)。

我们使用#(选项1 org.apache.commons.io.ioutils)转换到S3 ByteArray的对象。我们注意到,所以ioutils S3提供的方法转换到S3对象ByteArray,我们请求你确认什么是最好的方式来转换到一个ByteArray的S3对象避免延迟。

选项1:#

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

选项2:#

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

所以让我知道,如果我们有任何其他更好的方式来转换到S3 ByteArray的对象


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
         * 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);

这对我有用,

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

读取源内容()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
    }

编码序列()

1
2
3
4
5
6
7
8
9
10
11
12
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;
    }


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*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();
}


以下代码

1
2
3
4
5
6
7
8
9
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();
}

1
2
3
4
5
6
BufferedImage img = ...
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
ImageIO.write(img,"jpeg", baos);
baos.flush();
byte[] result = baos.toByteArray();
baos.close();