Java学习笔记-IO流

流的本质是数据传输,根据处理的数据类型不同,可以将流分为一下几类:

简要介绍

字节流:以字节(8bit)为单位,继承于两个抽象类InputStream(输入流)和OutputStream(输出流)(同时都是抽象类,只提供方法声明,不提供方法的具体实现)

字符流:一字符(16bit)为单位,继承于2个抽象类Reader(输入流),Writer(输出流)

两者的区别是:字节流不会用到缓存,但是字符流用到了缓存

缓存流:以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。 为了解决以上弊端,采用缓存流。缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

注:缓存流必须建立在一个存在的流的基础上 ,一次可以读取或者写入一行数据。有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush ,写一行,flush一次。

数据流:要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException,因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取

对象流:的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘 。一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口 。ObjectOutputStream和ObjectInputStream也需要基于FileInputStream 和FileOutputStream。

主要用于:

1、需要用网络来发送对象,或者对象的状态要持久化到数据库或者文件中。

2、序列化可以实现深复制,即可以复制引用的对象。

     过程,要实现序列化的类就要实现Serializable接口,该接口位于java.lang包中(里面没有任何方法),使用一个输出流(比如FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,然后使用该对象的writeObject(Object obj)方法就可以将obj对象写出(即保存其状态)。要恢复时使用对应的输入流。使用参考:https://how2j.cn/k/io/io-objectstream/351.html#nowhere

       注意,类的static成员和transient(临时数据)成员不能被序列化。

使用方法

  • 文件输入流(字节流)

这个流可以用来把数据从硬盘的文件,读取到JVM(内存)。FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取 。

 Java学习笔记-IO流

 

  • 文件输出流(字节流)

FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据

注:如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常。

 

Java学习笔记-IO流

注:流用完之后一定要关闭,否则产生巨大资源浪费。最后不要放在try中close,如果抛出异常,那么就不会关闭。可以放在finally中关闭。下面是标准的方法,但是因为比较麻烦,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式,因为不麻烦。

  • finally中关闭流

1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.

2. 在finally关闭之前,要先判断该引用是否为空

3. 关闭的时候,需要再一次进行try catch处理

Java学习笔记-IO流

 

  • 读取文件(字符流)

FileReader 是Reader子类,以FileReader 为例进行文件读取

Java学习笔记-IO流
     

FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了。而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK。FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:

new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"));

 

  • 文件写入(字符流)

FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

Java学习笔记-IO流