【java】字符流的比较

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

java的字符流被设定为对文件内部的数据进行读写操作的一组对象。

字符流和字节流的使用有很相似的地方,但字符流更针对文本文件的操作,因为他可以直接读取字符串。

学习字符流的具体使用之间,需要知道一点编码与解码的知识:

编码与解码

编码:就是将人类语言文字转换成二进制数据

解码:将二进制数据转化为人类语言文字。

所以这是一个相互作用的过程,当我们想要将数据,文件保存在计算机上,就必须考虑如何进行编解码。而且编解码不一致会产生错误,导致文件乱码。所以编解码应当使用同一套字符集(编解码表)。目前常用的编解码表为:

  • windows: GBK
  • idea等编译器工具: utf-8

java中的编解码方式

以字符串的转化为例:

  • 字符串-->byte字节数组
    • str.getBytes(),返回值是一个字节数组
    • str.getBytes(String charsetName),返回值是一个以charsetName编码表编码的字节数组
  • byte字节数组--> 字符串
    • new String(byte[] bytes),本质上是调用了String的构造方法,返回值是一个字符串
    • new String(byte[] bytes, String charsetName), 返回值是一个以charsetName编码表解码的字符串。

java中处理流的四种抽象基类

  • OutputStream:
  • InputStream
  • Writer
  • Reader

其中Writer和Reader两个抽象类专门用来处理字符,而OutputStream和InputStream用来处理字节流,更具有通用性。他们还有各种子类来实现不同的功能,常用的几个子类的继承关系如图:

IO继承关系.png

可以看到

共性1:四个抽象基类都实现了Closeable接口,实现了close()方法。这是因为他们都调用了jvm之外的系统资源(文件),每次对外部资源的使用都需要归还。

共性2:负责输出(比如将数据写入硬盘具体文件)的两个抽象基类都实现了Flushable接口, 调用flush方法是为了将任何缓冲的输出写入底层流。大多数情况下,这里的写入底层流都是指将缓冲区的数据写入外部资源(文件,网络)。

Writer的几个具体子类

Writer的几个具体子类有转换流(OutputStreamWriter),简化流(FileWriter)和缓冲流(BufferedWriter)。他们都实现了抽象父类Writer的write()方法,可以直接向文件输出字符串。

转换流(OutputStreamWriter)是一个包装流,他包装了一个OutStream流对象,使得可以在输出字节的基础上直接实现输出字符串的功能,方便写代码。而且可以在构造该对象时指定编码字符集。

简化流(FileWriter)在OutputStreamWriter的基础上进一步封装,是他的直接子类。不在需要指定OutStream对象,而是直接指定File对象即可创建一个简化流对象。这体现在他的构造器中。

image.png

而OutputStream类的构造器还需要指定输出流对象。

image.png

但简化流不能指定字符集,只能用当前操作平台的默认字符集进行编码。

当追求大文件读写速度时,Writer还有一个子类BufferedWriter缓冲流,自带默认大小为16KB的缓冲区,也可以在创建对象时指定缓冲区大小。缓冲流有自己独有的newLine()方法,可以向文件写入一个适配系统的换行。

Reader的几个具体子类

Reader的几个具体子类有转换流(InputStreamReader),简化流(FileReader)和缓冲流(BufferedReader)。他们都实现了抽象父类Reader的read()方法,可以读入单个字符,或者一次性读入一个字符数组。

转换流(InputStreamReader)是一个包装流,具体功能和他相对应的另一个负责输出的转换流一样。只不过成员方法是read方法。他也可以指定字符集,就是在构造时需要传入一个InputStream对象。

简化流(FileReader)在转换流的基础上进一步封装,是他的直接子类。只需要在构造时指定一个File对象。或者更简单的,指定一个文件名字符串就可以!真是名副其实的一个类!这体现在他的构造方法上:

image.png

缓冲流(BufferedReader)自带缓冲区,适合大文件读写,可以指定缓冲区大小,有自己独有的readLine()方法,可以一次性读取文件的一行数据,并返回该行形成的字符串。如果读到文件末尾,返回null。

需要注意的是,缓冲流也是一个包装流,在构造时需要传入一个Reader对象作为底层流,我们直接传入一个FileReader对象是最简单的方法!

猜你喜欢

转载自juejin.im/post/7102797053155082248