【问题标题】:Java - Resetting InputStreamJava - 重置输入流
【发布时间】:2013-09-18 14:03:12
【问题描述】:

我正在处理一些 Java 代码,其中有一个 InputStream,我读取了一次,然后我需要以相同的方法再次读取它。

问题是我需要将它的位置重新设置为开始才能读取它两次。

我找到了解决问题的方法:

is.mark(Integer.MAX_VALUE);

//Read the InputStream is fully
// { ... }

try
{
    is.reset();
}
catch (IOException e)
{
    e.printStackTrace();
}

此解决方案是否会导致一些意想不到的行为?或者它会在它的愚蠢中工作?

【问题讨论】:

  • 在读取代码也会mark()它的情况下可能会失败。
  • 你可以扩展InputStream,重写mark方法,使其在一个实例中只能调用一次。

标签: java input stream


【解决方案1】:

正如所写,你不能保证,因为mark() 不需要报告它是否成功。要获得保证,必须先调用markSupported(),它必须返回true

同样如书面,指定的读取限制是非常危险的。如果你碰巧使用了一个在内存中缓冲的流,它可能会分配一个 2GB 的缓冲区。另一方面,如果您碰巧使用的是FileInputStream,那就没问题了。

更好的方法是使用带有显式缓冲区的BufferedInputStream

【讨论】:

  • 也就是说一个BufferedInputStream可以被遍历两次?
  • @iMineLink - 是的,只要你给它足够大的缓冲区。没有什么东西可以在不消耗内存的情况下神奇地存储字节。如果这是一个问题,您需要将数据存储在本地文件中(根据其他 cmets,我假设您正在从套接字读取数据)。
  • 我的错没有很好地指定它:我正在从我认为充当 FileInputStream 的 getResourceAsStream(xyz) 返回的 InputStream 中读取数据。因此,我将尝试将其包装在具有显式缓冲区大小的 BufferedInputStream 中。
【解决方案2】:

这取决于 InputStream 的实现。也可以考虑用byte[]会不会更好。最简单的方法是使用Apache commons-io

byte[] bytes = IOUtils.toByteArray(inputSream);

【讨论】:

  • 字节[] 对我来说太重了,无法分配...我已经尝试过类似的方法,并且在某些 Android 设备上我得到了 OOM...我应该压缩它吗?在这种情况下我该怎么办?
  • 如果你使用的是SocketInputStream,你不能使用mark()来多次读取。如果您没有足够的内存将流数据保存为字节数组,您可以尝试将 InputStream 数据重定向到一个临时文件,然后您可以使用 BufferedInputStream (which supports mark()) 或随机访问文件。
【解决方案3】:

你不能可靠地做到这一点;一些InputStreams(例如连接到终端或套接字的那些)不支持markreset(参见markSupported)。如果真的要遍历两次数据,就需要读入自己的缓冲区。

【讨论】:

    【解决方案4】:

    不要尝试重置InputStream,而是将其加载到StringBuilder 之类的缓冲区中,或者如果它是二进制数据流,则加载ByteArrayOutputStream。然后,您可以根据需要多次在方法中处理缓冲区。

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
    int read = 0;
    byte[] buff = new byte[1024];
    while ((read = inStream.read(buff)) != -1) {
        bos.write(buff, 0, read);
    }
    byte[] streamData = bos.toByteArray();
    

    【讨论】:

    • 正如在其他类似答案中评论的那样,字节 [] 对我来说太重了,无法分配......
    【解决方案5】:

    对我来说,最简单的解决方案是传递可以从中获取 InputStream 的对象,然后再次获取它。就我而言,它来自ContentResolver

    【讨论】:

      猜你喜欢
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 2015-03-03
      相关资源
      最近更新 更多