Convert InputStream to byte array in Java

前端 未结 30 3484
無奈伤痛
無奈伤痛 2020-11-21 12:08

How do I read an entire InputStream into a byte array?

相关标签:
30条回答
  • 2020-11-21 12:32

    I know it's too late but here I think is cleaner solution that's more readable...

    /**
     * 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();
    }
    
    0 讨论(0)
  • 2020-11-21 12:33

    I tried to edit @numan's answer with a fix for writing garbage data but edit was rejected. While this short piece of code is nothing brilliant I can't see any other better answer. Here's what makes most sense to me:

    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 need not be closed. try/finally constructs omitted for readability

    0 讨论(0)
  • 2020-11-21 12:33

    Here is an optimized version, that tries to avoid copying data bytes as much as possible:

    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;
       }
    }
    
    0 讨论(0)
  • 2020-11-21 12:36
    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();
    
    0 讨论(0)
  • 2020-11-21 12:37

    If you happen to use google guava, it'll be as simple as :

    byte[] bytes = ByteStreams.toByteArray(inputStream);
    
    0 讨论(0)
  • 2020-11-21 12:37

    You're doing an extra copy if you use ByteArrayOutputStream. If you know the length of the stream before you start reading it (e.g. the InputStream is actually a FileInputStream, and you can call file.length() on the file, or the InputStream is a zipfile entry InputStream, and you can call zipEntry.length()), then it's far better to write directly into the byte[] array -- it uses half the memory, and saves time.

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

    N.B. the last line above deals with files getting truncated while the stream is being read, if you need to handle that possibility, but if the file gets longer while the stream is being read, the contents in the byte[] array will not be lengthened to include the new file content, the array will simply be truncated to the old length inputStreamLength.

    0 讨论(0)
提交回复
热议问题