复制InputStream的开头

时间:2011-08-21 03:03:56

标签: java inputstream reset

我想复制InputStream的“start”(即前N个字符),然后将流重置为它的开头,以便可以重复使用。

使用mark()和reset()不适用于所有类型的输入流,所以我想知道是否有一个“通用”开源Java类(即流包装器)可以为任何类型执行此操作输入流。

此外,制作副本以避免转换错误的最安全方法是什么?

4 个答案:

答案 0 :(得分:7)

也许你可以将你的InputStream包装在PushbackInputStream中,这样你就可以读取前N个字节,然后unread()来重复使用它们。

答案 1 :(得分:2)

看看apache如何通知IOUtils复制流IOUtils#copyLarge()

您可以使用填充ab ByteArrayInputStream这样的方式。

  • byte[] buffer = new byte[n]; // n是从开始的尺寸
  • 使用IOUtils#copyLarge()
  • 中的技术来填充缓冲区
  • 使用您之前创建的buffer
  • 创建ByteArrayInputStream

以下是IOUtils#copyLarge()

的代码段
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;
}

答案 2 :(得分:1)

在重用流时,大小无关紧要(例如几兆字节),获取流的byte[]一次,然后使用存储的{{{}重新创建ByteArrayInputStream个对象1}}必要时一直对我有用。 byte[]mark()不再有问题。

答案 3 :(得分:1)

经过相当多的实验,似乎最好(尽管不完美)的方法是使用InputStream的 mark() reset()方法。

如果原始流不支持标记/重置,一个简单的解决方法是将其包装在 BufferedInputStream 中。*