记录一个重复使用FileInputStream的bug

101 阅读1分钟

bug背景

现在的需求是,我需要读一个文件的输入流,然后拿到他的魔数,比较是否为指定的文件类型,之后再将输入流转储到文件系统中。

伪代码如下:

// 先得到输入流
InputStream is = getFileInputStream();
// 得到魔数,判断是否为png类型
String value = getFileHeader(is);
if(StringUtils.equals(value,PNG_TYPE_CODE)){
    saveToFile(is);
}

public String getFileHeader() {
    // 读取is的前6个字节,去获取魔术码,其他代码省略...
    byte[] b = new byte[6];
    is.read(b, 0, 6);    //..
}

这次,当我们将流存储到文件系统之后,发现文件大小几乎没什么区别,但是文件被损坏了,无法打开。原因如下:在得到魔数之后,因为已经读取了该流的前六个字节,此时指针向后移动,当我们再次使用该流时,指针的起始位置为上次操作后的位置,这就导致将其转换为文件时,丢失了前六个字节,文件因此损失。

解决方法:当我们得到魔数时,重新获取一次它的流,对该流进行操作,防止多次使用同一个流而导致异常。