- 方法 1
- 方法 2
我们知道,每次从 InputStream 对象中读取数据后,其当前读取位置的指针就会发生移动。如果在读取完的某时还想重新从此 InputStream 对象中读取数据,但此指针已到尽头,因此无法做到这一点。另外,InputStream 还不支持克隆,这意味着也不能事先备份这个 InputStream 对象。不过,这并不是没有办法。
方法 1如果使用的 InputStream 对象支持方法 mark,可以联合方法 reset 来进行 InputStream 对象的读取重置。方法是,先使用方法 mark 标记一个位置,然后之后在需要重置的时候,使用方法 reset 来将此 InputStream 对象重置到刚才的位置。
方法 mark 的使用规则如下。当 InputStream 对象调用方法 mark 时,它会在此 InputStream 对象的当前读取位置做一个标记。不过,它需要提供一个参数,这个参数是一个读取范围。在标记后继续从 InputStream 中读取数据时,如果读取到的数据大小超过了这个范围,则之后调用方法 reset 时将直接抛出异常。可以看出,在此处,这个参数没有太大的作用,最好设置为大于需要读取的数据大小,一般设置为在此 InputStream 对象的方法 available 的返回值即可。
使用模板如下:
// 如果此 inputStream 支持方法 mark
if (inputStream.markSupported()) {
try {
inputStream.mark(imageStream.available()); // 在当前位置作标记
} catch (IOException ioException) {
ioException.printStackTrace(); // TODO:处理异常
}
// TODO:从此 InputStream 对象中读取数据
try {
inputStream.reset(); // 将 inputStream 重置
} catch (IOException ioException) {
ioException.printStackTrace(); // TODO:处理异常
}
// TODO:重新开始从此 InputStream 对象中读取数据
try {
inputStream.reset(); // 将 inputStream 再次进行重置,以供以后可能进行的再次读取
} catch (IOException ioException) {
ioException.printStackTrace(); // TODO:处理异常
}
} else {
// TODO:如果不支持方法 mark,使用其它的办法
}
方法 2
如果使用的 InputStream 对象不支持方法 mark,可以考虑使用经典的方法,这种方法类似于深克隆的通用方法。可以先将此 InputStream 对象转化为另一种只读的独立的数据类型,然后再用此数据类型不断生成所需的 InputStream 对象。这种方法有很多,比方说,先将 InputStream 对象转化为 Byte 数组,然后创建一个 InputStream 对象来读取此 Byte 数组。但是,这种方法需要在一开始就从 InputStream 中读取完全部的数据,这样就会失去 InputStream 对象惰性读取的优势,因此最好使用上面的 方法 1。



