我有一个自定义格式的二进制文件,而不是我使用DataOutputStream编写的。文件中数据的简化格式为:IntCharIntCharIntChar…IntChar
我使用DataInputStream从这个文件中读取,并使用available()来确定下一次读取是否成功。
对于小文件,一切都很好。但是,对于大文件,文件大小大于Integer。MAX_VALUE字节,available()调用在第一次读取后返回奇怪的负值。我试图读取的文件是4751054632字节(约4.8 gig)。
简化测试代码:
DataInputStream reader=new DataInputStream(new BufferedInputStream(new FileInputStream("/path/file")));
System.out.println("available at start:t" + reader.available());
while(reader.available()>0){
int a=reader.readInt();
System.out.println("available after readInt:t" + reader.available());
char b=reader.readChar();
System.out.println("available after readChar:t" + reader.available());
//do something
}
输出:available at start: 2147483647 //this is equal to Integer.MAX_VALUE
available after readInt: -2147475461
available after readChar: -2147475463
而不是使用可用()我可以只是执行readInt()和readChar()命令在一个尝试块和捕获异常时,文件完成,但我试图理解为什么这种行为正在发生。从本质上讲,我正在寻找一个方法,将返回true,如果有可用的数据读取和false,如果文件完成/流已经结束。我认为可用()>0会做到这一点,但我想不是吗?
我使用DataInputStream从这个文件中读取,并使用available()来确定下一次读取是否成功。
那你做错了。请参阅Javadoc:"返回估计可以从该输入流读取(或跳过)的字节数,而不会在下一次调用该输入流的方法时阻塞。"许多实现返回零,而那些不返回零的实现不能保证返回正数:当有关的数字超过Integer.MAX_VALUE.
同时,available()
和read().
之间的文件大小也会发生变化
您应该通过捕获抛出它的方法上的EOFException
来检测流的结束,或者通过不返回的方法(即read()
,所有重载和readLine()
)返回-1或null
。