将 outputStream 转换为字节数组
converting outputStream to byte array
如何获取 outputStream 的字节,或者如何将 outputStream 转换为字节数组?
@Obicere 评论示例:
ByteArrayOutputStream btOs = new ByteArrayOutputStream();
btOs.write("test bytes".getBytes());
String restoredString = new String(btOs.toByteArray());
System.out.println(restoredString);
从理论的角度来看(即,不管它作为一个用例在实践中是否有意义),这是一个有趣的问题,本质上需要实现像
这样的方法
public abstract byte[] convert(OutputStream out);
Java
OutputStream
class,顾名思义,只支持 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[]
对象),class,从中实例化了相应的 OutputStream
对象,应该继续存储通过其 write()
方法处理的所有字节,并提供一个特殊的方法,例如 toByteArray()
,这将 return 全部,在调用时。
这正是 ByteArrayOutputStream
class 所做的,使 convert()
方法变得微不足道(并且不必要):
public byte[] convert(ByteArrayOutputStream out) {
return out.toByteArray();
}
对于任何其他类型的 OutputStream
,本质上不支持对 byte[]
对象的类似转换,在 OutputStream
被耗尽之前无法进行转换,即在完成对其 write()
方法的所需调用之前。
如果可以做出这样的假设(写入已经完成),并且如果可以替换原始 OutputStream
对象,那么一种选择是将其包装在委托中 class 本质上 "grab" 将通过其 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();
}
}
调用内部 "buffer" (ByteArrayOutputStream
) 的 write()
方法先于调用原始流(反过来,可以通过 super
,甚至通过 this.out
,因为 FilterOutputStream
的相应参数是 protected
)。这确保字节将被缓冲,即使在写入原始流时出现异常也是如此。
为了减少开销,可以省略上面 class 中对 super
的调用 - 例如,如果只需要对 byte
数组的 "conversion" .即使 ByteArrayOutputStream
或 OutputStream
classes 也可以用作父 classes,需要更多的工作和一些假设(例如,关于 reset()
方法).
在任何情况下,都必须有足够的内存才能进行排空并使 toByteArray()
方法起作用。
如何获取 outputStream 的字节,或者如何将 outputStream 转换为字节数组?
@Obicere 评论示例:
ByteArrayOutputStream btOs = new ByteArrayOutputStream();
btOs.write("test bytes".getBytes());
String restoredString = new String(btOs.toByteArray());
System.out.println(restoredString);
从理论的角度来看(即,不管它作为一个用例在实践中是否有意义),这是一个有趣的问题,本质上需要实现像
这样的方法public abstract byte[] convert(OutputStream out);
Java
OutputStream
class,顾名思义,只支持 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[]
对象),class,从中实例化了相应的 OutputStream
对象,应该继续存储通过其 write()
方法处理的所有字节,并提供一个特殊的方法,例如 toByteArray()
,这将 return 全部,在调用时。
这正是 ByteArrayOutputStream
class 所做的,使 convert()
方法变得微不足道(并且不必要):
public byte[] convert(ByteArrayOutputStream out) {
return out.toByteArray();
}
对于任何其他类型的 OutputStream
,本质上不支持对 byte[]
对象的类似转换,在 OutputStream
被耗尽之前无法进行转换,即在完成对其 write()
方法的所需调用之前。
如果可以做出这样的假设(写入已经完成),并且如果可以替换原始 OutputStream
对象,那么一种选择是将其包装在委托中 class 本质上 "grab" 将通过其 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();
}
}
调用内部 "buffer" (ByteArrayOutputStream
) 的 write()
方法先于调用原始流(反过来,可以通过 super
,甚至通过 this.out
,因为 FilterOutputStream
的相应参数是 protected
)。这确保字节将被缓冲,即使在写入原始流时出现异常也是如此。
为了减少开销,可以省略上面 class 中对 super
的调用 - 例如,如果只需要对 byte
数组的 "conversion" .即使 ByteArrayOutputStream
或 OutputStream
classes 也可以用作父 classes,需要更多的工作和一些假设(例如,关于 reset()
方法).
在任何情况下,都必须有足够的内存才能进行排空并使 toByteArray()
方法起作用。