java基础

IO流

2019-11-07  本文已影响0人  XXXX_ebc6

IO流详解

IO流结构图

4个基本的抽象流类型,所有的流都继承这四个。

输入流 输出流
字节流 InputStream outputStream
字符流 Reader Writer

inputStream:字节输入流


874710-20170530112251336-478728150.png

outputStream:字节输出流


874710-20170530121318274-160516931.png
Reader:字符输入流
874710-20170530121521321-799067835.png

Writer:字符输出流


874710-20170530121746211-57243059.png

IO流分类

按数据流的方向分为:输入流、输出流

此输入、输出时相对于内存而言的

输入流:从别的地方(本地文件,网络上的资源等)获取资源 输入到 内存中

输出流:从内存中 输出到 别的地方(本地文件), 将一个字符串保存到本地文件中,就需要使用输出流。

按处理数据单位不同分为 字节流、字符流

按不同编码,字符对应的字节数不同点此查看,若链接不到请翻到本文最下方

字节流:每次读取(写出)一个字节,当传输的资源文件有中文时,就会出现乱码

字符流:每次读取(写出)一个字符,有中文时,使用该流就可以正确传输显示中文

按功能不同分为:节点流,处理流

程序用于直接操作目标设备所对应的类叫节点流。

程序通过一个间接流类去调用节点流类,以达到更加灵活方便地读写各种类型的数据,这个间接流类就是处理流。

20170515115247115-1573109800025.jpg

Java IO流对象

输入字节流InputStream

ByteArrayInputStream:字节数组输入流,该类的功能就是从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去,我们拿也是从这个字节数组中拿

PipedInputStream:管道字节输入流,它和PipedOutputStream一起使用,能实现多线程间的管道通信

FilterInputStream :装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类。具体装饰者模式在下面会讲解到,到时就明白了

BufferedInputStream:缓冲流,对处理流进行装饰,增强,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送。效率更高

DataInputStream:数据输入流,它是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”

FileInputSream:文件输入流。它通常用于对文件进行读取操作

ObjectInputStream:对象输入流,用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象(反序列化中使用)

输出字节流

OutputStream 是所有的输出字节流的父类,它是一个抽象类。

ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,

ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流(序列化中使用)。

字符输入流Reader

Reader 是所有的输入字符流的父类,它是一个抽象类。

CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。

BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。

FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。

InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。

使用流时的选择

1、首先自己要知道是选择输入流还是输出流,这就要根据自己的情况而定,如果你想从程序写东西到别的地方,那么就选择输出流,反之用输入流

2、然后考虑你传输数据时,是选择使用字节流传输还是字符流,也就是每次传1个字节还是2个字节,有中文肯定就选择字符流了。

3、前面两步就可以选出一个合适的节点流了,比如字节输入流inputStream,如果要在此基础上增强功能,那么就在处理流中选择一个合适的即可。

流特性

1、先进先出,最先写入输出流的数据最先被输入流读取到。

2、顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile可以从文件的任意位置进行存取(输入输出)操作)

3、只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

装饰者模式

装饰模式的优点

(1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

装饰模式的缺点

由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

装饰者模式在Java IO流中的应用

装饰者模式在Java语言中的最著名的应用莫过于Java I/O标准库的设计了。
由于Java I/O库需要很多性能的各种组合,如果这些性能都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量性能重复的类出现。而如果采用装饰者模式,那么类的数目就会大大减少,性能的重复也可以减至最少。因此装饰者模式是Java I/O库的基本模式。

在字节流中,InputStream和OutputStream是被装饰者

在字符流中,Reader和Writer是被装饰者

字符编码

  • ASCII(数字、英文):1个字符占一个字节(所有的编码集都兼容ASCII)
  • ISO8859-1(欧洲):1个字符占一个字节
  • GB-2312/GBK:1个字符占两个字节
  • Unicode: 1个字符占两个字节(网络传输速度慢)
  • UTF-8:变长字节,对于英文一个字节,对于汉字两个或三个字节。

本文借鉴的博客:(博主分析的详细很多,如果有需要,请点击以下链接)

https://blog.csdn.net/sinat_37064286/article/details/86537354

上一篇 下一篇

猜你喜欢

热点阅读