Android基础之IO流

时间:2022-06-29 21:35:48

Java IO 按照不同类型来分,可以从以下几个方面来进行分类:

  • 输入/输出流

  • 字节流/字符流

  • 节点流/处理流

    对于前两个我们比较容易理解。那什么是节点流,什么是处理流呢。从斐青这篇文章中可以了解到:Java的IO使用装饰者模式将IO流分成了底层节点流和上层处理流。节点流直接和底层的物理存储节点关联,虽然不同的物理节点获取的节点流可能存在差异,但程序可以把不同的物理节点包装成统一的处理流,从而允许程序使用统一的IO代码来操作不同的物理节点。这就是封装的典型应用:不用考虑底层不同的节点流,只需将节点流封装成处理流来调用。

I/O流汇总

InputStream/Reader输入流
InputStream是字节输入流的抽象基类,其中有三个重要方法:

  • int read()
  • int read(byte[] b)
  • int read(byte[] b , int off ,int len)

都是将内容以字节(byte)的形式读取到输入流中。

Read是字符输入流的抽象基类,其中有三个重要方法:

  • int read()
  • int read(char[] b)
  • int read(char[] b , int off ,int len)

都是将内容以字符(char)的形式读取到输入流中。除此之外,两者还提供了skip()、reset()等方法。

OutputStream/Writer输入流

两个流都是从输出流写出数据到文件中,提供了如下三个方法:

  • void write(byte[]/char[] b)
  • void write(byte[]/char[] b, int off, int len)
  • void write(int b)

因为字符流直接以字符作为操作单位, 所以Writer可以用字符串来代替字符数组(以String对象作为参数). Writer还包含如下方法:

  • void write(String str)
  • void write(String str, int off, int len)
  • Writer append(char c)
  • Writer append(CharSequence csq)
  • Writer append(CharSequence csq, int start, int end)

Tips:

  • 使用Java IO流执行完IO后,不能忘记关闭流,关闭流才可以保证物理资源会被回收(关闭输出流还可以保证将缓冲区中的数据flush到物理节点中,因为在执行close()方法之前,会自动执行输出流的flush()方法).
  • 通常来说,字节流的功能比字符流的功能强大,因为计算机里所有的数据都是二进制的,因此字节流可以处理所有所有的二进制文件.
  • 如果使用字节流来处理文本文件,则需要将这些字节转换成字符,增加了编程的复杂度.所以有一个规则:如果进行IO是文本内容,则应该考虑使用字符流;如果进行IO的是二进制内容, 则应该考虑使用字节流.

节点流/处理流
节点流的的构造参数是物理IO节点,而处理流的构造参数是已经存在的流.

  • 常用节点流
    Android基础之IO流

  • 常用处理流
    Android基础之IO流

在使用处理流包装了节点流之后, 关闭输入/输出流资源时, 只要关闭最上层的处理流即可.关闭最上层的处理流时, 系统会自动关闭该处理流包装的节点流.
Tips
对于缓冲流,BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter 四个缓冲流增加了缓冲功能, 可以提高IO效率, 但是需要使用flush()才可以将缓冲区的内容写入实际的物理节点。(由于它的值都保存在内存中,所以流操作完成后需要flush())。

public class BufferWriterTest {

@Test

public void testBufferedWriter() throws IOException {

try (BufferedWriter writer = new BufferedWriter(new FileWriter("a.txt"))) {

writer.write("********");

writer.flush();

}

}

}

工具流(转换流)

  • InputStreamReader将字节输入流转换成字符输入流
  • OutputStreamWriter将字节输出流转换成字符输出流

参考这篇