愉快的记忆众多JavaIO类

前言

让时光积累真正的价值

最近在学习netty,要了解NIO,还是要对IO有一定的了解才行。之前看到了《Java IO,硬骨头也能变软》感觉写的非常的不错,但是我没有好好的做笔记,到后来都忘记了很多内容。

借这这个机会好好的做一个笔记。

这一篇笔记,主要是对JavaIO进行一个分类,方便自己好好记忆。

按照操作方式对IO进行分类

按照这种分类的方式,又可以再将IO流分成3类:

  • 字符流和字节流
  • 读流和写流\输入流和输出流
  • 节点流和处理流
字符流和字节流的特点

字符流:

  • 以字符为单位,每次读写都是操作8位数据,只能操作字符数据

字节流:

  • 以字节为单位,每次读写都是操作16位数据,能操作任意数据

在Java的原始版本中(java1.0),只有字节流,没有字符流。在Java1.1版本才把字符流加到IO的体系中。

需要特别注意:

所有的IO在最底层都是通过字节来交互的,字符流是一个经过了包装的字节流。提供字符流的目的是方便开发者操作字符数据。

怎么分辨字符流和字节流?

可以从类名来分辨,如果类名是xxxxReader或xxxxWriter的类基本上就是字符流了。

扫描二维码关注公众号,回复: 9820171 查看本文章

而类名是xxxOutputStream、xxxxInputStream结尾的基本上是字节流。

怎样把字节流转化为字符流?

很多时候,我们使用IO是在做一些字符串的操作。但是系统给我们提供的基础流都是一些字节流。我们常常需要将原来字节流转化为字符流。

有两个例子:

  • 获取键盘输入
BufferReader buffer = new BufferReader(new InputStreamReader(System.in));
复制代码

使用IO库提供的InputStreamReader,可以将InputStream转化为Reader流。配合缓冲流的包装就可以愉快的获取键盘的输入了。

  • 写入字符串到文件
 File sdf = new File("/");
FileOutputStream stream = new FileOutputStream(sdf);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));
writer.write("hell world");
复制代码

使用IO库提供的OutputStreamWriter,可以将OutputStream转化为Writer流。配合缓冲流的包装就可以直接向文件写入字符串了。

当然,这里也可以直接获取文件的字符流(FileWriter)来操作

输入流和输出流的特点

首先,输入和输出这两个概念都是相对与内存(或者是应用程序)来说的。

理解了这一个概念,什么是输入流什么是输出流很很容易分辨清楚了。

从外部载入到内存,比如xxxxReader、xxxxInputStream就是属于输入流。

从内存写到外部,比如xxxxWriter、xxxxOutputStream就是属于输出流。

节点流和处理流的特点

节点流:

  • 直接以外设为数据源或者的数据目的地,直接进行读取或者输出的操作,AIP相对不友好

操作流(过滤流):

  • 对已经存在节点流做一个包装,在节点流上封装一层用户友好的API

按照操作对象对IO进行分类

JavaIO 库中提供了一种链接的机制,可以将一个流套接到另外一个流上 ,最终形成一个流的管道链接,这种方式是装饰模式(设计模式)的典型应用。其中节点流就是装饰的原型(Component)。

操作流(过滤流):

  • 缓冲操作
  • 基本数据类型操作
  • 对象序列化操作
  • 转化控制
  • 打印控制

节点流:

  • 文件操作
  • 管道操作
  • 数组操作
缓冲操作:

在操作流的时候先将数据写入一个缓冲区,可以避免直接和硬盘、外设等速度非常缓慢的IO设备打交道,节约了大量的等待时间。

比如键盘输入的例子,将字节流转换为字符流之后,BufferedReader先将数据添加到缓冲区,等到一定的条件之后才将数据从缓冲区里面取出来。

缓冲操作流有:

  • BufferedReader
  • BufferedWriter
  • BufferedInputStream
  • BufferedOutputStream
基本数据类型操作:

内存与外设之间传输数据一般都是以0101的数据来做交互,如果要传输一个基本数据类型(int、sort、long)怎么办?

我们可以使用基本数据类型转换流来套接字节流,这样就可以向流的另外一段传送一个Java的基本数据类型了。

基本类型转换流有:

  • DataOutputStream
  • DataInputStream
对象序列化操作:

怎么将一个Java的对象,转化成0101数据传送到流的另外一端?Java提供了对象序列化转化流解决这个问题。

对象序列化相关的流有:

  • ObjectOutputStream
  • ObjectIntputStream
转化控制:

想要直接操作字符串,但是原生流是字节流,怎么办?

可以使用转化流将字节流转化为字符流

转化流有:

  • InputStreamReader
  • OutputStreamReader
打印控制:

提供了很多打印相关的便利操作,其中system.out就是一个打印流。不限于命令行打印,我们可以使用println、printfAPI对任意的外设进行操作。

打印流有:

  • PrintStream
  • PrintWriter
文件操作:

对应外设是文件,我们可以提供Java提供的API打开相关的文件字符流、文件字节流。文件流提供输入流、输出流、字节流、字符流。

文件流有:

  • FileWriter
  • FileReader
  • FileOutputStream
  • FileInputStream
管道操作

查阅资料,管道流是用来在线程之间传输数据的,没怎么了解过。

管道流有:

  • PipedInputStream
  • PipedOutStream
  • PipedReader
  • PipedWriter
数组流:

在内存中开辟一块数组作为数据源。有一个特点就是可重复读取。在有重复读取需求的地方将数据源的数据加载进数组流中,然后就可以重复从数组流中读取数据了。但是这样做有可能会对内存造成太大的负担。

数组流有:

  • ByteArrayInputStream
  • ByteArrayOutputStream
  • charArrayReader
  • charArrayWriter

最后

参考:《Java IO,硬骨头也能变软

猜你喜欢

转载自juejin.im/post/5e6b4a06f265da574d10222f
今日推荐