IO流的分类与设计之基础知识

IO流的分类与设计之基础知识

java.io包中的IO流

java.io包中类太多了,简直是…“琳琅满目”“眼花缭乱”。你第一次(第二次,第三次,。。。)看到这些API时,“哦”愁眉苦脸时,放心,你不是唯一受到惊吓和困扰的人。但是,如果你好好梳理他们的关系,并掌握几个经典代表的使用方式,其他的也就等于掌握了。

第一:其实不管有多少种IO流,最基本的只有四个。
IO的四个超级父类,抽象基类。

  • 字节输入流:InputStream
  • 字节输出流:OutputStream
  • 字符输入流:Reader
  • 字符输出流:Writer

第二:IO流类的设计选用了“装饰者”设计模式,即IO流分为两大类,“被装饰”的组件和“装饰”的组件。
例如:以InputStream为例
其中FileInputStream、ByteArrayInputStream等是“被装饰”的组件,依次用来连接和读取“文件”、“内存中的字节数组”的等。
而BufferedInputStream、DataInputStream、ObjectInputStream等是用来“装饰”的组件,依次是给其他InputStream的IO流提供装饰的辅助功能的,依次可以增加“提高效率的缓冲功能”、“按照Java数据类型读取数据的能力”、“读取并恢复Java对象的能力”等
你会发现OutputStream、Reader、Writer系列的流设计方式也是一样的。

第三:IO流的选取可以通过以下几个分类来简化选取过程。
按照IO流的方向:输入流和输出流

  • I:代表Input
  • O:代表Output
    Java的IO流是单向的,只能从输入流(Input、Reader)中读取(read)数据,也只能往输出流(Output、Writer)中写(write、print)出数据。

按照IO流的处理数据的基本单位分:

  • 字节流(XxxStream):直接处理二进制,一个字节一个字节处理,它适用于一切数据,包括纯文本、doc、xls、图片、音频、视频等等
  • 字符流(XxxReader和XxxWriter):一个字符一个字符处理,只能纯文本类的数据。

按照角色分:节点流、处理流

  • 节点流:连接源头、目的地,即被装饰者IO流
  • 处理流:增强功能,提高性能,即装饰者IO流

节点流处于IO操作的第一线,所有操作必须通过他们进行;
处理流是通过包装节点流来完成功能的,处理流可以增加很多层。
处理流必须依赖和包装节点流,而不能单独存在。

在这里插入图片描述

常见IO流

在这里插入图片描述

抽象基类的常用方法

1、InputStream

(1)int read()
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
(2)int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取的字节数。
(3)int read(byte[] b, int off,int len)
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1.
(4)public void close() throws IOException关闭此输入流并释放与该流关联的所有系统资源。

2、OutputStream

(1)void write(int b)
将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的
(2)void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同。
(3)void write(byte[] b,int off,int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
(4)public void flush()throws IOException 刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。
(5)public void close() throws IOException关闭此输出流并释放与该流关联的所有系统资源。

3、Reader

(1)int read()
读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个字节的Unicode码),如果已到达流的末尾,则返回 -1
(2)int read(char[] cbuf)
将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
(3)int read(char[] cbuf,int off,int len)
将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
(4)public void close() throws IOException关闭此输入流并释放与该流关联的所有系统资源。

4、Writer

(1)void write(int c)、Writer append(char c)
写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即写入0 到 65535 之间的Unicode码。
(2)void write(char[] cbuf)、Writer append(CharSequence csq)
写入字符数组。
(3)void write(char[] cbuf,int off,int len)、Writer append(CharSequence csq, int start, int end)
写入字符数组的某一部分。从off开始,写入len个字符
(4)void write(String str)
写入字符串。
(5)void write(String str,int off,int len)
写入字符串的某一部分。
(6)void flush()
刷新该流的缓冲,则立即将它们写入预期目标。
(7)public void close() throws IOException关闭此输出流并释放与该流关联的所有系统资源。

IO流使用步骤

1、读取/接收数据的步骤

第一步:选择IO流

1、选择节点流
明确你要从哪里读取数据,即数据源是什么?
如果从文件中,就选择FileInputStream、FileReader;
如果从内存的数组中,就选择ByteArrayInputStream、CharArrayReader;
如果从网络中,就选择InputStream;
2、选择字节流还是字符流
如果可选,那么看数据是否是纯文本,如果是纯文本并且文本的编码方式与当前平台的编码方式一致,那么选择字符流的效率更高,否则选择字节流。
3、是否需要增加额外的辅助功能
缓冲功能:BufferedReader、BufferedInputStream
是否需要按行读:BufferedReader、Scanner
是否需要以与机器无关方式从底层输入流中读取基本 Java 数据类型:DataInputStream
是否需要对象的反序列化:ObjectInputStream
是否需要对流中的数据进行解码的转换:InputStreamReader

第二步:循环读取数据
  • read()
  • readLine()
  • readXxx(),例如:readInt(),readObject(),readUTF()等
第三步:关闭close()

2、写/发送数据的步骤

第一步:选择IO流

1、选择节点流
明确你要把数据写到哪里去,即数据的目的地是哪里?
如果写到文件中,就选择FileOutputStream、FileWriter;
如果写到内存某数组中,就选择ByteArrayOutputStream、CharArrayWriter;
如果发送到网络中,就选择OutputStream;
2、选择字节流还是字符流
如果可选,那么看数据是否是纯文本,如果是纯文本并且文本的编码方式与当前平台的编码方式一致,那么选择字符流的效率更高,否则选择字节流。
3、是否需要增加额外的辅助功能
缓冲功能:BufferedOutputStream、BufferedWriter
是否需要按行写:PrintStream、PrintWriter
是否需要以以适当方式将基本 Java 数据类型写入输出流:DataOutputStream
是否需要将对象的序列化:ObjectOutputStream
是否需要对流中的数据进行编码的转换:OutputStreamWriter

第二步:循环写数据
  • write(xx)
  • print(xx)和println(xx)
  • writeXxx:例如:writeInt(xx)、writeDouble(xx)、writeObject(xx)等
第三步:关闭IO流close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值