对于BufferedInputStream类中的mark(int readlimit)方法的使用,很多人的疑惑是:参数readlimit究竟起什么作用?
好象给readlimit赋任何整数值结果都是一样。
1 package io;
2
3 import java.io.*;
4
5 public class BufInputStrm_A {
6
7 public static void main(String[] args) throws IOException {
8 String s = "ABCDEFGHI@JKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
9 byte[] buf = s.getBytes();
10 ByteArrayInputStream in = new ByteArrayInputStream(buf);
11 BufferedInputStream bis = new BufferedInputStream(in, 13);
12 int i = 0;
13 int k;
14 do {
15 k = bis.read();
16 System.out.print((char) k + " ");
17 i++;
18
19 if (i == 4) {
20 bis.mark(8);
21 }
22 } while (k != '@');
23
24 System.out.println();
25
26 bis.reset();
27 k = bis.read();
28 while (k != -1) {
29
30 System.out.print((char) k + " ");
31 k = bis.read();
32 }
33
34 }
35 }
36
备注:为了方便说明问题,我们假设要读取的是一个字符串(第8行代码),同时把缓存的大小设置为了13(第11行代码)。
在第20行代码处调用了mark(int readlimit)方法,但无论给该方法传-1、0、13、100程序输出的结果都是一样:
A B C D E F G H I @
E F G H I @ J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z
在官方的API帮助文档中,对于readlimit这个参数的解释是:
readlimit
- the maximum limit of bytes that can be read before the mark position becomes invalid.
其实,这里的最大字节数(the maximum limit of bytes)是指调用reset()方法之后,读取超过readlimit指定的字节数,标记维(the mark position)会失效,如果这时再次调用reset()方法,会出现
Resetting to invalid mark异常。例如下面的程序:
1 package io;
2
3 import java.io.*;
4
5 public class BufInputStrm_A {
6
7 public static void main(String[] args) throws IOException {
8 String s = "ABCDEFGHI@JKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
9 byte[] buf = s.getBytes();
10 ByteArrayInputStream in = new ByteArrayInputStream(buf);
11 BufferedInputStream bis = new BufferedInputStream(in, 13);
12 int i = 0;
13 int k;
14 do {
15 k = bis.read();
16 System.out.print((char) k + " ");
17 i++;
18
19 if (i == 4) {
20 bis.mark(8);
21 }
22 } while (k != '@');
23
24 System.out.println();
25
26 bis.reset();
27 k = bis.read();
28 while (k != -1) {
29
30 System.out.print((char) k + " ");
31 k = bis.read();
32 }
33
34 System.out.println();
35
36 bis.reset();
37 k = bis.read();
38 while (k != -1) {
39 System.out.print((char) k + " ");
40 k = bis.read();
41
42 }
43
44 }
45 }
46
如果我们在第一次调用了reset()方法之后,控制读入的字节不超过8个,程序就会正常执行,例如我们对上面的程序的26-32代码用下面的代码替换,程序就可以正常运行了。
bis.reset();
int j = 1;
k = bis.read();
while (j < 9) {
System.out.print((char) k + " ");
k = bis.read();
j++;
}
补充:
在mark(int readlimit)方法的代码中,readlimit的值会赋给数据域marklimit,如果marklimit的值大于缓冲区的值BufferedInputStream会对缓冲区的大小进行调整,调整为marklimit的值。
----------------------------------
把人做到宽容,把技术做到强悍。