关于BufferedInputStream类的mark与reset方法的一个bug的问题
2010-11-26 18:51
537 查看
关于BufferedInputStream类的mark与reset方法的一个bug的问题.txt
sylilzy@gmail.com
施祖阳 http://www.shizuyang.cn
2010-7-7 13:20:26 星期三
最近在调试程序时发现BufferedInputStream类的mark与reset方法存在一个bug,重现方式如下:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class BugTest {
/**
* @param args
*/
static public void main(String[] p) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("e://temp//a.txt"));
int available = bis.available();
System.out.println("available:" + available);
// ---
int markLimit = available;
bis.mark(markLimit);
System.out.println("---mark:" + markLimit);
byte[] temp = new byte[available];
bis.read(temp);
System.out.println("---read:" + available);
System.out.println("---read one byte:" + bis.read());
bis.reset();
System.out.println("reset ok!");
bis.close();
}
}
在以上类运行时,如果e://temp//a.txt文件的大小在8192字节以上,则运行结果如下:
available:8384
---mark:8384
---read:8384
---read one byte:-1
Exception in thread "main" java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(Unknown Source)
at com.BugTest.main(BugTest.java:22)
如果e://temp//a.txt文件的大小在8192字节以下,则不会有此异常。
为了分析问题产生的原因,我写了如下一个类来显示BufferedInputStream类的相关信息:
import java.io.BufferedInputStream;
import java.io.InputStream;
public class MyBuffer extends BufferedInputStream {
public MyBuffer(InputStream in, int size) {
super(in, size);
// TODO Auto-generated constructor stub
}
public MyBuffer(InputStream in) {
super(in);
// TODO Auto-generated constructor stub
}
public int getMarklimit() {
return marklimit;
}
public int getMarkPosition() {
return markpos;
}
public int getBufferLength() {
return buf.length;
}
}
测试类修改如下:
import java.io.*;
import java.util.regex.Pattern;
/**
* @author shizy TODO To change the template for this generated type comment go
* to Window - Preferences - Java - Code Style - Code Templates
*/
public class Test {
static public void main(String[] p) throws Exception {
MyBuffer bis = new MyBuffer(new FileInputStream("e://temp//a.txt"));
int available = bis.available();
System.out.println("available:" + available);
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
// ---
int markLimit = available;
bis.mark(markLimit);
System.out.println("---mark:" + markLimit);
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
byte[] temp = new byte[available];
bis.read(temp);
System.out.println("---read:" + available);
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
System.out.println("---read one byte:" + bis.read());
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
bis.reset();
System.out.println("reset ok!");
bis.close();
}
}
则运行结果如下:
available:8384
getBufferLength:8192
getMarklimit:0
getMarkPosition:-1
---mark:8384
getBufferLength:8192
getMarklimit:8384
getMarkPosition:0
---read:8384
getBufferLength:8384
getMarklimit:8384
getMarkPosition:0
---read one byte:-1
getBufferLength:8384
getMarklimit:8384
getMarkPosition:-1
Exception in thread "main" java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(Unknown Source)
at com.Test.main(Test.java:41)
可见,在输出了“---read:8384”后,BufferLength变成了与Marklimit一样的大小,但在"---read one byte:-1"后,MarkPosition变成了-1,导致了reset时出错。
解决办法有三种:
1.增加BufferedInputStream的BufferLength,在上例中,增加到8385则可解决问题。但此大小需要由输入流的数据量解定,此方法并不太可行。
2.改变markLimit大小。将int markLimit = available;修改为:int markLimit = available+1;。采用这种方式,则上例运行结果如下:
available:8384
getBufferLength:8192
getMarklimit:0
getMarkPosition:-1
---mark:8385
getBufferLength:8192
getMarklimit:8385
getMarkPosition:0
---read:8384
getBufferLength:8385
getMarklimit:8385
getMarkPosition:0
---read one byte:-1
getBufferLength:8385
getMarklimit:8385
getMarkPosition:0
reset ok!
3.不要在流数据结束之后再调用bis.read方法,这种方法并不能完全保证不出问题,因为流数据是否结束,必须要通过read的返回值才能知道。
看来,此问题的出现情况是当BufferLength刚好与从输入流读入的数据相等时(缓冲区会随着marklimit大小增长),如果再读入数据,即时此时未读入数据,则也会认为超过了Marklimit限制,则reset会抛出异常。
注:
jdk版本:
java version "1.6.0_05"
Java(TM) SE Runtime Environment (build 1.6.0_05-b13)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)
sylilzy@gmail.com
施祖阳 http://www.shizuyang.cn
2010-7-7 13:20:26 星期三
最近在调试程序时发现BufferedInputStream类的mark与reset方法存在一个bug,重现方式如下:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class BugTest {
/**
* @param args
*/
static public void main(String[] p) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("e://temp//a.txt"));
int available = bis.available();
System.out.println("available:" + available);
// ---
int markLimit = available;
bis.mark(markLimit);
System.out.println("---mark:" + markLimit);
byte[] temp = new byte[available];
bis.read(temp);
System.out.println("---read:" + available);
System.out.println("---read one byte:" + bis.read());
bis.reset();
System.out.println("reset ok!");
bis.close();
}
}
在以上类运行时,如果e://temp//a.txt文件的大小在8192字节以上,则运行结果如下:
available:8384
---mark:8384
---read:8384
---read one byte:-1
Exception in thread "main" java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(Unknown Source)
at com.BugTest.main(BugTest.java:22)
如果e://temp//a.txt文件的大小在8192字节以下,则不会有此异常。
为了分析问题产生的原因,我写了如下一个类来显示BufferedInputStream类的相关信息:
import java.io.BufferedInputStream;
import java.io.InputStream;
public class MyBuffer extends BufferedInputStream {
public MyBuffer(InputStream in, int size) {
super(in, size);
// TODO Auto-generated constructor stub
}
public MyBuffer(InputStream in) {
super(in);
// TODO Auto-generated constructor stub
}
public int getMarklimit() {
return marklimit;
}
public int getMarkPosition() {
return markpos;
}
public int getBufferLength() {
return buf.length;
}
}
测试类修改如下:
import java.io.*;
import java.util.regex.Pattern;
/**
* @author shizy TODO To change the template for this generated type comment go
* to Window - Preferences - Java - Code Style - Code Templates
*/
public class Test {
static public void main(String[] p) throws Exception {
MyBuffer bis = new MyBuffer(new FileInputStream("e://temp//a.txt"));
int available = bis.available();
System.out.println("available:" + available);
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
// ---
int markLimit = available;
bis.mark(markLimit);
System.out.println("---mark:" + markLimit);
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
byte[] temp = new byte[available];
bis.read(temp);
System.out.println("---read:" + available);
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
System.out.println("---read one byte:" + bis.read());
System.out.println("getBufferLength:" + bis.getBufferLength());
System.out.println("getMarklimit:" + bis.getMarklimit());
System.out.println("getMarkPosition:" + bis.getMarkPosition());
bis.reset();
System.out.println("reset ok!");
bis.close();
}
}
则运行结果如下:
available:8384
getBufferLength:8192
getMarklimit:0
getMarkPosition:-1
---mark:8384
getBufferLength:8192
getMarklimit:8384
getMarkPosition:0
---read:8384
getBufferLength:8384
getMarklimit:8384
getMarkPosition:0
---read one byte:-1
getBufferLength:8384
getMarklimit:8384
getMarkPosition:-1
Exception in thread "main" java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(Unknown Source)
at com.Test.main(Test.java:41)
可见,在输出了“---read:8384”后,BufferLength变成了与Marklimit一样的大小,但在"---read one byte:-1"后,MarkPosition变成了-1,导致了reset时出错。
解决办法有三种:
1.增加BufferedInputStream的BufferLength,在上例中,增加到8385则可解决问题。但此大小需要由输入流的数据量解定,此方法并不太可行。
2.改变markLimit大小。将int markLimit = available;修改为:int markLimit = available+1;。采用这种方式,则上例运行结果如下:
available:8384
getBufferLength:8192
getMarklimit:0
getMarkPosition:-1
---mark:8385
getBufferLength:8192
getMarklimit:8385
getMarkPosition:0
---read:8384
getBufferLength:8385
getMarklimit:8385
getMarkPosition:0
---read one byte:-1
getBufferLength:8385
getMarklimit:8385
getMarkPosition:0
reset ok!
3.不要在流数据结束之后再调用bis.read方法,这种方法并不能完全保证不出问题,因为流数据是否结束,必须要通过read的返回值才能知道。
看来,此问题的出现情况是当BufferLength刚好与从输入流读入的数据相等时(缓冲区会随着marklimit大小增长),如果再读入数据,即时此时未读入数据,则也会认为超过了Marklimit限制,则reset会抛出异常。
注:
jdk版本:
java version "1.6.0_05"
Java(TM) SE Runtime Environment (build 1.6.0_05-b13)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)
相关文章推荐
- 关于Java构造方法的一个问题
- 关于DropDownList的一个问题(很想说是BUG)
- JS中关于call()方法的一个问题(转自百度知道,解答非常详细清楚)
- CSS IE6、7下关于Position的一个bug问题分享
- 关于jQuery EasyUI 中刷新Tab选项卡 后一个页面变形的问题的解决方法
- 今天修了一个bug,关于debug日志的问题
- C# 关于out关键字的用法(一个方法返回多个值的问题)
- DataGuard - 一个关于Physical Standby中recover问题的解决方法
- 关于一个困扰一晚上的bug -- java 返回值问题
- 今天遇到一个关于STL中排序的问题, 怀疑是sort的bug!
- 一个关于ConfigurationManager.GetSecion方法的小问题
- 关于FreeMarker获取一个对象中另一个对象出现的问题以及解决方法
- 关于ASP.NET“操作必须使用一个可更新的查询”问题的解决方法
- 一个bug关于frame的问题
- DataGuard - 一个关于Physical Standby中recover问题的解决方法
- 关于一个字符出现1次或者n次输出问题的解决方法
- VS2005中的一个小BUG:关于Dropdownlist无法Datadinding的解决方法。
- JAVA学习中,一个关于Object对象转换时对应方法的问题
- 分享关于学习new BufferedWriter()方法时常遇到的一个无厘头的问题
- 关于类继承中子类方法比父类方法丰富,一个引用值传递的小问题