将outputStream转换为字节数组 [英] converting outputStream to byte array

查看:423
本文介绍了将outputStream转换为字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取outputStream的字节,或者如何将outputStream转换为字节数组?

How can I get the bytes of an outputStream, or how can I convert an outputStream to a byte array?

推荐答案

从理论上讲(即,无论在实际中是否作为用例都有意义),这是一个有趣的问题,本质上要求实现一个像

From a theoretical perspective (i.e., irrespective of whether it makes sense in practice as a use case), this is an interesting question that essentially requires the implementation of a method like

public abstract byte[] convert(OutputStream out);

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

The Java OutputStream class, as its name implies, only supports an overridden write() method for I/O, and that write() method gets either an integer (representing 1 byte) or a byte array, the contents of which it sends to an output (e.g., a file).

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

For example, the following code saves the bytes already present in the data array, to the output.txt file:

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

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

In order to get all the data that a given OutputStream will be outputting and put it into a byte array (i.e., into a byte[] object), the class from which the corresponding OutputStream object was instantiated, should keep storing all the bytes processed via its write() methods and provide a special method, such as toByteArray(), that would return them all, upon invocation.

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

This is exactly what the ByteArrayOutputStream class does, making the convert() method trivial (and unnecessary):

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

对于任何其他类型的OutputStream,并不固有地支持对byte[]对象的类似转换,在耗尽OutputStream之前,即在所需的方法已完成.

For any other type of OutputStream, not inherently supporting a similar conversion to a byte[] object, there is no way to make the conversion, before the OutputStream is drained, i.e. before the desired calls to its write() methods have been completed.

如果可以做出这样的假设(写操作已经完成),并且如果可以替换原始的OutputStream对象,则一种选择是将其包装在一个委托类中,该委托类实际上将抓住"对象.通过其write()方法提供的字节数.例如:

If such an assumption (of the writes to have been completed) can be made, and if the original OutputStream object can be replaced, then one option is to wrap it inside a delegate class that would essentially "grab" the bytes that would be supplied via its write() methods. For example:

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

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

The calls to the write() methods of the internal "buffer" (ByteArrayOutputStream) precede the calls to the original stream (which, in turn, can be accessed via super, or even via this.out, since the corresponding parameter of the FilterOutputStream is protected). This makes sure that the bytes will be buffered, even if there is an exception while writing to the original stream.

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

To reduce the overhead, the calls to super in the above class can be omitted - e.g., if only the "conversion" to a byte array is desired. Even the ByteArrayOutputStream or OutputStream classes can be used as parent classes, with a bit more work and some assumptions (e.g., about the reset() method).

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

In any case, enough memory has to be available for the draining to take place and for the toByteArray() method to work.

这篇关于将outputStream转换为字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆