This question already has answers here:
How to convert outputStream to a byte array?
                                
                                    (4个答案)
                                
                        
                                2年前关闭。
            
                    
如何获取outputStream的字节,或者如何将outputStream转换为字节数组?

最佳答案

从理论上讲(即,不管在实践中是否作为用例有意义),这是一个有趣的问题,本质上要求实现类似

public abstract byte[] convert(OutputStream out);


顾名思义,Java OutputStream类仅支持用于I / O的重写的write()方法,并且write()方法获取整数(表示1个字节)或byte数组,其内容它发送到输出(例如文件)。

例如,以下代码将data数组中已经存在的字节保存到output.txt文件中:

byte[] data = ... // Get some data
OutputStream fos = new FileOutputStream("path/to/output.txt");
fos.write(data);


为了获取给定OutputStream将要输出的所有数据并将其放入byte数组(即放入byte[]对象),应从中实例化相应的OutputStream对象的类。继续存储通过其write()方法处理的所有字节,并提供一个特殊方法(例如toByteArray()),该方法在调用时将全部返回。

这正是ByteArrayOutputStream类的作用,使convert()方法变得微不足道(且不必要):

public byte[] convert(ByteArrayOutputStream out) {
  return out.toByteArray();
}


对于OutputStream的任何其他类型,固有地不支持对byte[]对象的类似转换,在OutputStream耗尽之前,即在期望的对其write()方法的调用之前,无法进行转换。已经完成。

如果可以做出这样的假设(假设已完成写操作),并且可以替换原始的OutputStream对象,则一种选择是将其包装在一个委托类中,该委托类实际上将“获取”将要使用的字节。通过其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();
  }
}


内部“缓冲区”(write())的ByteArrayOutputStream方法的调用先于原始流的调用(依次可通过super或什至通过this.out进行访问,因为相应的FilterOutputStream的参数是protected)。这样可确保即使写入原始流时发生异常,也将缓冲字节。

为了减少开销,可以省略对上述类中的super的调用-例如,如果仅需要“转换”为byte数组。甚至ByteArrayOutputStreamOutputStream类都可以用作父类,这需要更多的工作和一些假设(例如,关于reset()方法)。

在任何情况下,都必须有足够的内存来进行排空和toByteArray()方法起作用。

关于java - 将outputStream转换为字节数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43081008/

10-10 23:03
查看更多