如何将outputStream转换为字节数组?

61

如何将OutputStream转换为字节数组?我发现首先需要将OutputStream转换为ByteArrayOutputStream。在这个OutputStream类中只有write()方法,我不知道该怎么办。有什么想法吗?


使用toByteArray方法来提取字节。 - Deepak Bala
1
严格来说,你不能这样做。一个输出流就是一个输出流就是一个输出流。一旦它存在,你或许可以将其包装在PrintStream中或其他类似的方式。 - Ingo
5个回答

103

创建一个ByteArrayOutputStream

通过调用toByteArray()获取其内容。

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
baos.writeTo(myOutputStream); 
baos.toByteArray();

参考资料


7
对于像我一样一无所知的人:ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.writeTo(myOutputStream); baos.toByteArray();这段代码创建了一个名为 baos 的字节数组输出流对象,它可以在内存中动态地将字节写入数组缓冲区。writeTo() 方法将输出流中的字节写入指定的输出流 myOutputStream 中。toByteArray() 方法返回输出流中当前的字节数组。 - Bruce Loth
旁边的问题。相比于baos.toByteArray()baos.toString()有什么限制吗?我先在一些旧项目中使用了它,但由于某种原因,我无法从中生成SHA-1哈希摘要,但对于第二个项目来说却很好用,而且我仍然不知道为什么,可能是读取文件时出了问题。 - JackTheKnife

6
如果提供的 OutputStream 对象不是一个 ByteArrayOutputStream,可以将其包装在一个委托类中,该类将“获取”传递给 write() 方法的字节,例如:
public class DrainableOutputStream extends FilterOutputStream {
  private final ByteArrayOutputStream buffer;
  public DrainableOutputStream(OutputStream out) {
    super(out);
    this.buffer = new ByteArrayOutputStream();
  }
  @Override
  public void write(byte b[]) throws IOException {
    this.buffer.write(b);
    super.write(b);
  }
  @Override
  public void write(byte b[], int off, int len) throws IOException {
    this.buffer.write(b, off, len);
    super.write(b, off, len);
  }
  @Override
  public void write(int b) throws IOException {
    this.buffer.write(b);    
    super.write(b);
  }
  public byte[] toByteArray() {
    return this.buffer.toByteArray();
  }
}

为了减少开销,可以省略上述类中对super的调用 - 例如,如果只需要"转换"为字节数组。
更详细的讨论可在另一个StackOverflow问题中找到。

3

你需要做两件事情:

  • 使用ByteArrayOutputStream向其中写入内容
  • 使用toByteArray()方法,你将得到内容的byte[]数组

你甚至可以像这里提到的那样进行扩展。


0
如果您尝试ByteArrayOutputStream bos=(ByteArrayOutputStream)outputStream,则会抛出ClassCastException。我在从HttpServletResponse获取OutputStream时遇到了这个问题,它是CoyoteOutputStream。(您可以创建文件,因此不要创建临时文件)。
您可以使用Java反射OutputStream转换为byte[]
 byte[] bytes = this.getBytes(outStream);

/**
 * Get byte from OutputStream
 *
 * @param outStream
 * @return
 */
@SneakyThrows
private byte[] getBytes(OutputStream outStream) {
    OutputBuffer outputBuffer = (OutputBuffer) this.getValueByName("ob", outStream);
    ByteBuffer byteBuffer = (ByteBuffer) this.getValueByName("bb", outputBuffer);
    return (byte[]) this.getValueByName("hb", byteBuffer);
}

/**
 * Get value from property
 *
 * @param name
 * @param value
 * @return
 */
@SneakyThrows
@SuppressWarnings("unchecked")
private Object getValueByName(String name, Object value) {
    List<Field> listFiled = new ArrayList<>();
    if (value.getClass().getSuperclass() != null) {
        listFiled.addAll(Arrays.asList(value.getClass().getSuperclass().getDeclaredFields()));
    }
    listFiled.addAll(Arrays.asList(value.getClass().getDeclaredFields()));
    Optional<Field> fieldOb = listFiled.stream()
        .filter(field -> StringUtils.equalsAnyIgnoreCase(name, field.getName()))
        .findFirst();
    if (fieldOb.isPresent()) {
        Field field = fieldOb.get();
        field.setAccessible(true);
        return field.get(value);
    }
    return StringUtils.EMPTY; // FIXME
}

0
你可以将输出流声明为一个 ByteArrayOutputStream,然后使用 ByteArrayOutputStream#toByteArray() 方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接