相信BufferedReader应该是大家所熟悉的一个操作类,但是其中的mark,reset方法,不知大家是否有过关注,
近日工作中碰到问题,不解,所以就Google并记录下来,给自己个记录,也希望与大家分享。
关于BufferedReader:
public class BufferedReader
extends Reader
Read text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.
In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,
BufferedReader in
= new BufferedReader(new FileReader("foo.in"));
will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.
Programs that use DataInputStreams for textual input can be localized by replacing each DataInputStream with an appropriate BufferedReader.
Since:
JDK1.1
See Also:
FileReader, InputStreamReader
关于它的mark,reset方法:
mark
public void mark(int readAheadLimit)
throws IOException
Mark the present position in the stream. Subsequent calls to reset() will attempt to reposition the stream to this point.
Overrides:
mark in class Reader
Parameters:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After reading this many characters, attempting to reset the stream may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.
Throws:
IllegalArgumentException - If readAheadLimit is < 0
IOException - If an I/O error occurs
reset
public void reset()
throws IOException
Reset the stream to the most recent mark.
Overrides:
reset in class Reader
Throws:
IOException - If the stream has never been marked, or if the mark has been invalidated
在项目中有如下代码:
protected static String readToTag(BufferedReader br)
{
String string = "";
try
{
br.mark(9);
int charVal = br.read();
while (charVal != '<' && !isFileEnd(br))
{
if(charVal == '\r'){
currentLineNo ++;
}
string += (char)charVal;
br.mark(9);
charVal = br.read();
}
br.reset();
if (isFileEnd(br) && charVal>0)
{
string += (char)charVal;
}
return (string);
}
catch (IOException ioe)
{
Message.show(Message.error, ioe.getMessage());
return (null);
}
}
其功能是:在html文件解析中,读取当前BufferedReader至第一个tag。
其实,BufferedReader的功能是有很多用处的,比如统计文件行数,在html中读取发现tag后再将文件指针返回指向tag前面的位置;
1.在上面的code中,我查阅后(原作者已离职)的理解是:此处就是要
在当前处mark一下,读取下一个char后,判断是否'<',重复画线处,直到发现'<',然后返回tag前的文本;则此处的9(就是这个9害我思索许久),不一定是9,可以是8,7...2,后面只读一次就又mark了; 1不行(后面讨论)。
2.在文件读取中,使用mark方法时,要注意,要设置mark参数int readAheadLimit=file.length + 1,否则就会爆出异常java.io.IOException: Mark invalid.
原因在于:
jdk中声明:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After
reading this many characters, attempting to reset the stream may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.
英文声明可能有些confused,来看中文的:
readAheadLimit - 在仍保留该标记的情况下,对可读取字符数量的限制。在
读取达到或超过此限制的字符后,尝试重置流可能会失败。限制值大于输入缓冲区的大小将导致分配一个新缓冲区,其大小不小于该限制值。因此应该小心使用较大的值。 //就是建议使用大于最大值的值
给大家一段代码可以参考运行:
import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
String s = "Message.show(Message.error, ioe.getMessage()).一";
char buf[] = new char[s.length()];
s.getChars(0, s.length(), buf, 0);
CharArrayReader in = new CharArrayReader(buf);
BufferedReader f = new BufferedReader(in);
String d = "";
int c;
System.out.println(s.length() );
f.mark(s.length() +1);
while ((c = f.read()) != -1) {
d += (char)c;
}
f.reset();
System.out.println(d);
}
}