【问题标题】:Convert InputStream to byte array in Java在 Java 中将 InputStream 转换为字节数组
【发布时间】:2010-11-18 21:07:04
【问题描述】:

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

【问题讨论】:

标签: java bytearray inputstream


【解决方案1】:

您需要从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);
}

return buffer.toByteArray();

【讨论】:

  • 新创建的字节[]的大小如何。为什么是16384?我怎样才能确定完全正确的尺寸?非常感谢。
  • 16384 是一个相当随意的选择,尽管我倾向于使用 2 的幂来增加数组与单词边界对齐的机会。 pihentagy 的回答显示了如何避免使用中间缓冲区,而是分配正确大小的数组。除非你处理的是大文件,否则我个人更喜欢上面的代码,它更优雅,可用于预先不知道要读取的字节数的 InputStreams。
  • @Adamski 创建的字节数组不是比您预期的要大得多,数据会在流中,浪费内存吗?
  • @bluesm:是的,没错。但是,在我的示例中,字节数组只有 16Kb,按照今天的标准来说是如此之小。另外,当然这块内存之后会再次被释放。
  • @Adamski 很多基础设施硬件、网络服务器和操作系统层组件都在使用 4K 缓冲区来移动数据,所以这就是确切数字的原因,但重点是你得到了超过 4K 的性能提升如此之小,以至于通常被认为是浪费内存。我假设这是仍然正确的,因为这是我十年前的知识!
【解决方案2】:

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

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

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

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

【讨论】:

  • 为了写4行代码,你觉得导入3rd-party依赖值得吗?
  • 如果有一个库可以处理需求,并处理大文件的处理,并且经过良好测试,那么问题肯定是我为什么要自己编写它? jar 只有 107KB,如果您需要其中的一种方法,您可能也会使用其他方法
  • @oxbow_lakes:考虑到我在开发人员生活中看到的该功能的错误实现数量惊人,我觉得是的是非常非常值得外部依赖来让它正确。
  • 为什么不去看看像FastArrayList 这样的Apache commons 或者他们的软弱参考地图,然后回来告诉我这个库是多么“经过良好测试”。一堆垃圾
  • 除了 Apache commons-io,查看 Google Guava 中的 ByteStreams 类。 InputStream is;byte[] filedata=ByteStreams.toByteArray(is);
【解决方案3】:

以下代码

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

【讨论】:

    【解决方案4】:

    你真的需要byte[] 的图片吗?您对byte[] 的期望究竟是什么——图像文件的完整内容,以图像文件的任何格式编码,还是 RGB 像素值?

    此处的其他答案向您展示如何将文件读入byte[]。您的 byte[] 将包含文件的确切内容,您需要对其进行解码才能对图像数据执行任何操作。

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

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

    另请参阅以下教程:Working with Images

    【讨论】:

      【解决方案5】:
      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();
      

      【讨论】:

      • 然而,通常操作系统已经有足够的缓冲,因此对于较小的文件来说这不是一个大问题。这不像硬盘磁头会单独读取每个字节(硬盘是一块转动的玻璃板,上面有磁编码信息,有点像我们用来保存数据的那个奇怪的图标:P)。
      • @Maarten Bodewes:大多数设备都有一种块传输,所以并不是每个 read() 都会导致实际的设备访问,但是每个字节都有一个操作系统调用已经足以杀死表现。虽然将 InputStream 包装在 BufferedInputStream 之前,该代码会减少操作系统调用并显着减轻性能缺陷,但该代码仍会执行从一个缓冲区到另一个缓冲区的不必要的手动复制工作。
      【解决方案6】:
      /*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();
      }
      

      【讨论】:

      • 关闭和刷新 bos 是浪费键盘点击。关闭输入流更有可能有所帮助。一次读取一个字节是低效的。请参阅 numan 的回答。
      【解决方案7】:

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

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

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

      【讨论】:

      • 取决于预先知道的尺寸。
      • 当然可以,但他们应该知道大小:“我想读取图像”
      • 如果您知道大小,那么 java 会为您提供代码。查看我的答案或谷歌“DataInputStream”,它是 readFully 方法。
      • 如果offset &lt; bytes.length 则应添加is.close(),否则如果抛出该异常,InputStream 将不会关闭。
      • 那更好,你应该使用 try-with-resources
      【解决方案8】:

      使用 vanilla Java 的 DataInputStream 及其 readFully 方法(至少从 Java 1.4 开始存在):

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

      此方法还有其他一些风格,但我一直在此用例中使用它。

      【讨论】:

      • +1 用于使用标准库而不是 3rd 方依赖项。不幸的是,它对我不起作用,因为我不知道预先流的长度。
      • @janus 它是一个“文件”。这种方式只有在你知道文件的长度或要读取的字节数时才有效。
      • 有趣的事情,但您必须知道要读取的(部分)流的确切长度。此外,DataInputStream 类主要用于从流中读取主要类型(Longs、Shorts、Chars...),因此我们可以将这种用法视为对类的滥用。
      • 如果你已经知道要从流中读取的数据长度,这并不比InputStream.read好。
      • @LoganPickup InputStream.read 不保证返回您请求的所有字节!
      【解决方案9】:

      我尝试使用写入垃圾数据的修复程序来编辑 @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();
      

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

      【讨论】:

        【解决方案10】:
        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();
        }
        

        【讨论】:

        • 这是一个例子,因此简洁是当务之急。在某些情况下,在此处返回 null 也是正确的选择(尽管在生产环境中您也会有适当的异常处理和文档)。
        • 我理解一个例子的简洁性,但为什么不让示例方法抛出 IOException 而不是吞下它并返回一个无意义的值呢?
        • 我冒昧地将'return null'更改为'throw IOException'
        • Try-with-resources 在这里不需要,因为 ByteArrayOutputStream#close() 什么都不做。 (不需要 ByteArrayOutputStream#flush() 也什么都不做。)
        【解决方案11】:
        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();
        

        【讨论】:

          【解决方案12】:

          如果你碰巧用了Google Guava,那就和ByteStreams一样简单:

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

          【讨论】:

            【解决方案13】:

            如果你不想使用 Apache commons-io 库,这个 sn-p 取自 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;
            }
            

            【讨论】:

            • 这有点奇怪,length 是数组长度的上限。如果你知道长度,你只需要: byte[] output = new byte[length]; is.read(输出); (但看我的回答)
            • @luke-hutchison 正如我所说,这是 sun.misc.IOUtils 的解决方案。在最常见的情况下,您预先不知道 InputStream 的大小,所以 if (length == -1) length = Integer.MAX_VALUE;适用。即使给定长度大于 InputStream 的长度,此解决方案也有效。
            • @LukeHutchison 如果你知道长度,你可以用几行来处理它。如果你看每个答案,每个人都在抱怨长度不知道。最后是一个标准的答案,可以与 Java 7 Android 一起使用,并且不需要任何外部库。
            【解决方案14】:

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

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

            【讨论】:

              【解决方案15】:

              我知道为时已晚,但我认为这里是更清晰的解决方案,更具可读性...

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

              【讨论】:

              • 你应该使用 try-with-resources。
              • 你最后的整理需要在 finally 块中完成,以防出错,否则可能导致内存泄漏。
              【解决方案16】:

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

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

              【讨论】:

                【解决方案17】:

                如果您使用 ByteArrayOutputStream,您正在做一个额外的副本。如果你在开始读之前就知道了流的长度(比如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);
                

                注意上面的最后一行处理在读取流时文件被截断,如果您需要处理这种可能性,但是如果在读取流时文件变得 longer,则字节 [ ] 数组不会被加长以包含新的文件内容,数组只会被截断为旧长度inputStreamLength

                【讨论】:

                  【解决方案18】:

                  这对我有用,

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

                  编码字符串()

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

                  【讨论】:

                  【解决方案19】:

                  请参阅InputStream.available() 文档:

                  意识到你不能使用这个是特别重要的 方法来调整容器的大小并假设您可以阅读全部内容 流,而无需调整容器的大小。这样的来电者 可能应该将他们读取的所有内容写入 ByteArrayOutputStream 并将其转换为字节数组。或者,如果您正在阅读 从文件中,File.length 返回文件的当前长度 (虽然假设文件的长度不能改变可能是不正确的, 读取文件本质上是活泼的)。

                  【讨论】:

                    【解决方案20】:

                    我用这个。

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

                    【讨论】:

                    • 添加一些解释,说明此答案如何帮助 OP 解决当前问题
                    【解决方案21】:

                    这是我的复制粘贴版本:

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

                    【讨论】:

                    • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
                    【解决方案22】:

                    Java 7 及更高版本:

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

                    【讨论】:

                    • sun.misc.IOUtils 不是“Java 7”。它是一个专有的、特定于实现的类,可能不存在于其他 JRE 实现中,并且可以在下一个版本中消失而不会发出任何警告。
                    【解决方案23】:

                    终于,在 20 年后,有一个不需要 3rd 方库的简单解决方案,感谢Java 9

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

                    还要注意readNBytes(byte[] b, int off, int len)transferTo(OutputStream) 解决重复性需求的便捷方法。

                    【讨论】:

                    • Java 文档 “请注意,此方法适用于可以方便地将所有字节读入字节数组的简单情况。它不适用于读取具有大量数据的输入流。”事实上,我的测试仅限于 8192(未记录)将其用于测试,但不在生产中。
                    • @pdem 没有这样的限制。我刚刚通过将 2GiB 文件读入内存来验证它。只要可以分配适当大的数组,它就可以工作。如果你得到不同的结果,那是你的测试设置的问题。您不应该将如此大的文件读入内存,而是更喜欢在阅读时处理它们,这一点完全不同。它显然适用于问答中提出的所有解决方案,因为它们都是关于将整个文件读入内存。
                    • 嗯,你非常被动,我已经测试了 2 个 jdk (11 17),它可以与你所说的大字节输入流一起工​​作,所以我猜可能 api 有一个问题,它是一个 javamail:我从 mimemessage 内容中获取文件。奇怪的是,javamail相关的bug,在经典的手册阅读中并没有出现。
                    • 这个特定的InputStream 是否覆盖readAllBytes()readNBytes
                    • 听起来值得单独提出一个问题。
                    【解决方案24】:

                    如果由于某种原因不在表格中,请将其包装在 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;
                    }
                    

                    【讨论】:

                      【解决方案25】:

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

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

                      【讨论】:

                      • 这和InputStram.readAllBytes()那是单线有什么区别?
                      • ByteArrayOutputStream 中肯定有很多数组调整大小,然后是数据的完整副本。
                      【解决方案26】:

                      与往常一样,Spring framework(自 3.2.2 以来的 spring-core)也为您提供了一些东西:StreamUtils.copyToByteArray()

                      【讨论】:

                      • 像大多数其他人一样,我想避免将 3rd 方库用于如此简单的事情,但 Java 9 目前不是一个选择......幸运的是,我已经在使用 Spring。
                      【解决方案27】:

                      如果有人仍在寻找没有依赖关系的解决方案并且如果您有文件

                      数据输入流

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

                      字节数组输出流

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

                      随机存取文件

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

                      【讨论】:

                      • 说,如果字节数组太大导致堆OOM怎么办?是否有类似的解决方案将使用 JNI 来存储字节,然后我们就可以从存储在那里的数据中使用 inputStream(某种临时缓存)?
                      • 对不起,我不小心对这个答案投了反对票。您能否编辑一些字符以便我可以撤消单击?谢谢!
                      • 谢谢,@MichaelOuyang。希望我的回答对你有帮助:)
                      【解决方案28】:

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

                      请注意,此解决方案会擦除回车('\r')并且可能不合适。

                      【讨论】:

                      • 那是String。 OP 要求byte[]
                      • 不仅仅是\r 可能是个问题。此方法将字节转换为字符并再次转换回来(使用 InputStreamReader 的默认字符集)。任何在默认字符编码中无效的字节(例如,Linux 上的 UTF-8 为 -1)都将被损坏,甚至可能更改字节数。
                      • 似乎这是一个很好的答案,但面向文本。买家小心。
                      【解决方案29】:

                      你可以试试Cactoos:

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

                      【讨论】:

                        【解决方案30】:

                        在将 S3 对象转换为 ByteArray 时,我们看到一些 AWS 事务出现延迟。

                        注意:S3 对象是 PDF 文档(最大大小为 3 mb)。

                        我们使用选项 #1 (org.apache.commons.io.IOUtils) 将 S3 对象转换为 ByteArray。我们注意到 S3 提供了内置 IOUtils 方法来将 S3 对象转换为 ByteArray,我们要求您确认将 S3 对象转换为 ByteArray 的最佳方法是什么,以避免延迟。

                        选项#1:

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

                        选项#2:

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

                        如果我们有其他更好的方法将 s3 对象转换为字节数组,请告诉我

                        【讨论】:

                          猜你喜欢
                          • 2012-09-26
                          • 2011-01-10
                          • 2010-12-20
                          • 2011-10-05
                          • 1970-01-01
                          • 2013-08-14
                          • 2013-09-27
                          相关资源
                          最近更新 更多