【发布时间】:2011-08-21 03:03:56
【问题描述】:
我想复制 InputStream 的“开始”(即前 N 个字符),然后将流重置为其开始,以便可以重复使用。
使用 mark() 和 reset() 不适用于所有类型的输入流,所以我想知道是否有一个“通用”开源 Java 类(即流包装器)可以对任何类型执行此操作输入流。
另外,为了避免转换错误,制作副本的最安全方法是什么?
【问题讨论】:
标签: java inputstream reset
我想复制 InputStream 的“开始”(即前 N 个字符),然后将流重置为其开始,以便可以重复使用。
使用 mark() 和 reset() 不适用于所有类型的输入流,所以我想知道是否有一个“通用”开源 Java 类(即流包装器)可以对任何类型执行此操作输入流。
另外,为了避免转换错误,制作副本的最安全方法是什么?
【问题讨论】:
标签: java inputstream reset
也许您可以将 InputStream 包装在 PushbackInputStream 中,这样您就可以读取前 N 个字节,然后再读取 unread() 它们以重复使用流。
【讨论】:
看看 apache commons IOUtils 如何复制流IOUtils#copyLarge()。
你可以这样使用populate ab ByteArrayInputStream。
byte[] buffer = new byte[n]; // n 是从开始的大小IOUtils#copyLarge() 中的技术填充缓冲区
buffer 创建您的 ByteArrayInputStream这里是IOUtils#copyLarge()的代码sn-p
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
【讨论】:
在重用流和大小无关紧要(例如几兆字节)时,获取流的byte[] 一次,然后在必要时使用存储的byte[] 重新创建ByteArrayInputStream 对象一直为我工作。 mark() 和 reset() 不再麻烦。
【讨论】:
经过相当多的实验,似乎最好的(虽然不完美)方法是使用 InputStream 的 mark() 和 reset() 方法。
如果原始流不支持标记/重置,一个简单的解决方法是将其包装在 BufferedInputStream 中。*
【讨论】: