java入门之字符流、字节流与介质流、过滤流

java的各种输入流输出流关系有些复杂,对于像我这种初学者来说理清他们需要不少时间,所以我把我的理解整理出来,希望能够帮助到将来的初学者以及纠正我自己理解上的问题。


字节流和字符流之间的区别很明显,字节流以8bit的字节为单位从流中读取,所以不能读取汉字字符,java中的抽象基类是InputStream和OutputStream,字符流以字符(Unicode等)为单位读取,并且会自动判断字符的起止,所以可以读取一个字节的英文和两个字节的汉字,抽象基类是Reader和Writer。


介质流则是单纯继承抽象基类的流,比如说StringBufferInputStream(内存读取),ByteArrayInputStream(内存读取),FileInputStream(文件读取),System.in(键盘读取)继承了InputStream。

另外,System.in是java.lang包中提供的标准输入流,方便进行应用程序以及终端之间的数据交换,类似的标准数据流还有System.out和System.err,但这两个继承的不是抽象基类而是接下来要说到的字节流的过滤流PrintStream。


在理解过滤流之前要先了解装饰设计模式,如下图

java入门之字符流、字节流与介质流、过滤流_第1张图片

为了实现不同的功能,不使用装饰设计模式时需要创建许多不同的类的对象造成麻烦,而使用如下格式则可以用一个对象实现不同的功能组合:

Decorator decorator = new Decorator(new ConcreteDecoratorA(new ConcreteDecoratorB(new ConcreteComponent())));
因为所有的类都继承了Component类,而Decorator还关联了一个Component类,所以理论上只要在new Decorator时不断地用新的Decorator作为参数,就能实现任意功能的组合。


比如继承而且关联了InputStream的过滤流FilterInputStream以及继承了FilterInputStream的DataInputStream和BufferedInputStream可以这样声明:

DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("File.txt")));
只要是InputStream的子类就可以作为构造函数中的参数,大大减少了代码需要的对象数。

同理继承而且关联了OutputStream的过滤流FilterOutputStream以及继承了FilterOutputStream的PrintStream也可以如上声明。


字符流的过滤流同理所以不再赘述,只将比较常用的字符流写在下面:

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
BufferedReader fileIn = new BufferedReader(new FileReader("file.txt"));
PrintWriter stdOut = new PrintWriter(System.out, true);
PrintWriter fileOut = new PrintWriter(new FileWriter("file.txt",true),true);//允许在原文件基础上输出,自动刷新缓冲区
PrintWriter stdErr = new PrintWriter(System.err, true);
需要注意的是介质流System.in作为参数时需要用InputStreamReader转换为过滤流,而System.out和System.err已经是过滤流则不需要转换。

以上就是对于介质流和过滤流的简单理解,难免有错漏之处,望各位读者不吝赐教。

你可能感兴趣的:(数据流)