郑州餐饮 网站建设,网站建设 项目经验,网站建设 加盟,通信管理局网站备案抽象基类之二
FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流#xff0c;并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能#xff0c;以及mark()和res…抽象基类之二
FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能以及mark()和reset()功能”。
InputStream和Reader提供的一些移动指针的方法void mark(int readlimit ); 在记录指针当前位置记录一个标记mark。boolean markSupported(); 判断此输入流是否支持mark()操作即是否支持记录标记。void reset(); 将此流的记录指针重新定位到上一次记录标记mark的位置。long skip(long n); 记录指针向前移动n个字节/字符。 readlimit 参数给出当前输入流在标记位置变为非法前允许读取的字节数。 这句话的意思是说mark就像书签一样用于标记以后再调用reset时就可以再回到这个mark过的地方。mark方法有个参数通过这个整型参数告诉系统希望在读出多少个字符之前这个mark保持有效。 比如说mark(10)那么在read()10个以内的字符时reset()操作指针可以回到标记的地方然后重新读取已经读过的数据如果已经读取的数据超过10个那reset()操作后就不能正确读取以前的数据了mark()打标记已经失效reset()会报错。 但实际的运行情况却和JAVA文档中的描述并不完全相符。 有时候在BufferedInputStream类中调用mark(int readlimit)方法后即使读取超过readlimit字节的数据mark标记仍可能有效仍然能正确调用reset方法重置。 事实上mark在JAVA中的实现是和缓冲区相关的。只要缓冲区够大mark后读取的数据没有超出缓冲区的大小mark标记就不会失效。如果不够大mark后又读取了大量的数据导致缓冲区更新原来标记的位置自然找不到了。 因此mark后读取多少字节才失效并不完全由readlimit参数确定也和BufferedInputStream类的缓冲区大小有关。 如果BufferedInputStream类的缓冲区大小大于readlimit在mark以后只有读取超过缓冲区大小的数据mark标记才会失效。
public class test1 {public static void main(String[] args) throws IOException {byte[] bnew byte[] {1,2,3,4,5};//把数组转为数组输入流ByteArrayInputStream bais new ByteArrayInputStream(b);//进行一次封装封装时指定缓冲区大小,先指定2个字节大小BufferedInputStream bis new BufferedInputStream(bais,2);//先读出第一个字节数据出来,指针会指向第二个字节即2上面System.out.println(bis.read()); // 1//现在指针在2上打一个标记bis.mark(1); //按官方文档来说,读第一个数据出来后标记会失效reset()方法会报错事实上不会报错,经过测试是缓冲区bis读三个数据时//大小缓冲区大小缓冲区装不下了标记才有用。System.out.println(bis.read()); //2System.out.println(bis.read()); //3bis.reset();System.out.println(bis.read()); //2}}
----------------------------------------------------------------------------
1
2
3
2当连续读三个数据时缓冲区(2个字节大小装不下标记才会失效
public class test1 {public static void main(String[] args) throws IOException {byte[] bnew byte[] {1,2,3,4,5};//把数组转为数组输入流ByteArrayInputStream bais new ByteArrayInputStream(b);//进行一次封装封装时指定缓冲区大小,先指定2个字节大小BufferedInputStream bis new BufferedInputStream(bais,2);//先读出第一个字节数据出来,指针会指向第二个字节即2上面System.out.println(bis.read()); // 1//现在指针在2上打一个标记bis.mark(1); //按官方文档来说,读第一个数据出来后标记会失效reset()方法会报错事实上不会报错,经过测试是缓冲区bis读三个数据时//大小缓冲区大小缓冲区装不下了标记才有用。System.out.println(bis.read()); //2System.out.println(bis.read()); //3System.out.println(bis.read()); //4bis.reset();System.out.println(bis.read()); 没有数据打印并报错了}}
----------------------------------------------------------------------------
1
2
3
4
Exception in thread main java.io.IOException: Resetting to invalid markat java.io.BufferedInputStream.reset(Unknown Source)at cn.ybzy.io.filter.test1.main(test1.java:33)不设标记不重设定位正常读没问题
public class test1 {public static void main(String[] args) throws IOException {byte[] bnew byte[] {1,2,3,4,5};//把数组转为数组输入流ByteArrayInputStream bais new ByteArrayInputStream(b);//进行一次封装封装时指定缓冲区大小,先指定2个字节大小BufferedInputStream bis new BufferedInputStream(bais,2);System.out.println(bis.read()); // 1System.out.println(bis.read()); //2System.out.println(bis.read()); //3System.out.println(bis.read()); //4System.out.println(bis.read()); //5}}(2) DataInputStream 是用来装饰其它输入流它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。 应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据。
FilterOutputStream FilterOutputStream 的作用是用来“封装其它的输出流并为它们提供额外的功能”。 它主要包括BufferedOutputStream, DataOutputStream和PrintStream。 (1) BufferedOutputStream的作用就是为“输出流提供缓冲功能”。 (2) DataOutputStream 是用来装饰其它输出流将DataOutputStream和DataInputStream输入流配合使用 “允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。
打印流PrintStream PrintStream是用来装饰其它输出流。它能为其他输出流添加了功能使它们能够方便地打印各种数据值表示形式。 打印流提供了非常方便的打印功能可以打印任何类型的数据信息例如小数整数字符串。 之前打印信息需要使用OutputStream但是这样所有数据输出会非常麻烦PrintStream可以把OutputStream类重新包装了一下使之输出更方便。
public class PrintStreamTest {public static void main(String[] args) throws FileNotFoundException {FileOutputStream fos new FileOutputStream(c:\\c.txt);PrintStream printnew PrintStream(fos);print.print(xiongshaowen);print.print(123);print.print(12.3);print.print(new Object());print.close();}}格式化输出 JAVA对PrintStream功能进行了扩充增加了格式化输出功能。直接使用Print即可。但是输出的时候需要指定输出的数据类型。
public class PrintStreamTest {public static void main(String[] args) throws FileNotFoundException {FileOutputStream fos new FileOutputStream(c:\\c.txt);PrintStream psnew PrintStream(fos);/*print.print(xiongshaowen);print.print(123);print.print(12.3);print.println(new Object());print.close();*///格式打印int i 10;String s打印流;float f 15.5f;ps.printf(整数 %d,字符串 %s,浮点数 %f,i,s,f);ps.println();ps.printf(整数 [%d],字符串 %s,浮点数 %f,i,s,f);ps.close();}} 推回输入流的使用
通常我们使用输入流的时候我们读取输入流是顺序读取当读取的不是我们想要的怎么办又不能放回去虽然我们可以使用程序做其他的处理来解决但是Java提供了推回输入流来解决这个问题 推回输入流可以做这样子的事情将已经读取出来的字节或字符数组内容推回到推回缓冲区里面 从而允许重复读取刚刚读取的我们不想要的东西之前内容
注意当程序创建一个推回输入流时需要指定推回缓冲区的大小默认的推回缓冲区长度为一 如果程序推回到推回缓冲区的内容超出了推回缓冲区的大小将会引发Pushback buffer overflow 异常。 程序举例 假如盘下有一个aa.txt文件内容如下我现在只想读取aaa前面的内容后面的我不想要。
public class TuiHuistream {public static void main(String[] args) throws IOException {//1文件流2字符流 3输入流Reader reader new FileReader(C:\\aa.txt);PushbackReader pr new PushbackReader(reader,1024);//从输入流中读取数据char[] cs new char[5];int hasReadCount 0;String sumString;int count0; //计数器看看下面读了多少次数据while((hasReadCountpr.read(cs))!-1) {String curString new String(cs,0,hasReadCount);sumString sumStringcurString;count;int aaaIndex sumString.indexOf(aaa); //这里我们以aaa’为标记推回aaa之前的内容到缓冲区中if(aaaIndex-1) {pr.unread(sumString.toCharArray()); //把所有内容推到缓冲区中cs//重新把我想要的内容即aaa之前的内容读出来if(aaaIndex 5) {cs new char[aaaIndex];//扩容缓冲区}pr.read(cs,0,cs.length);System.out.println(我想要的内容为:new String(cs));break;}else {System.out.println(new String(cs));}}System.out.println(一共读了多少次count次);pr.close();}}
------------------------------------------------------------------------------------------------------------------------------
ccccc
ccccc
ccccc
cc
c
cccca
我想要的内容为:ccccccccccccccccc
ccccc
一共读了多少次6次