Java第二阶段JavaSE2(IO流)

JAVA IO

1.Java定义了两个超类(抽象类):

          java.io.InputStream 输入流,这个类是所有字节输入流的超类,规定了所有字节输入
  流读取数据的相关方法。
          java.io.OutputStream 输出流,这个类是所有字节输出流的超类,规定了所有字节输出
  流写出数据的相关方法。

2.   实际应用中,我们连接不同的设备,java都专门提供了用于连接它的输入流与输出流,而这些负责实际连接设备的流称为节点流,也叫低级流。是真实负责读写数据的流.与之对应的还有高级流,高级流可以连接其他的流,目的是当数据流经它们时,对数据做某
种加工处理,用来简化我们的操作.

java将流分为两类:节点流与处理流:

  • 节点流:也称为低级流.节点流的另一端是明确的,是实际读写数据的流,读写一定是建立在节点流基础上进行的.

  • 处理流:也称为高级流.处理流不能独立存在,必须连接在其他流上,目的是当数据流经当前流时对数据进行加工处理来简化我们对数据的该操作.

一、FileInputStream/FileOutputStream(低级流/节点流)(字节流)

 1.文件流

  java.io.FileInputStream和FileOutputStream
  这是一对低级流,继承自InputStream和OutputStream。用于读写硬盘上文件的流

2.块读写的文件复制操作

        int read(byte[] data) 一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中。 返回值为实际读取到的字节量。若返回值为-1则表示读取到了文件末尾。

        块写操作 void write(byte[] data) 一次性将给定的字节数组所有字节写入到文件中

        void write(byte[] data,int offset,int len) 一次性将给定的字节数组从下标offset处开始的连续len个字节写入文件

3.写文本数据

String提供方法: byte[] getBytes(String charsetName) 将当前字符串转换为一组字节

参数为字符集的名字,常用的是UTF-8。 其中中文字3字节表示1个,英文1字节表示1个。

4.文件输出流-追加模式

重载的构造方法可以将文件输出流创建为追加模式

  • FileOutputStream(String path,boolean append)

  • FileOutputStream(File file,boolean append)

当第二个参数传入true时,文件流为追加模式,即:指定的文件若存在,则原有数据保留,新写入的数据会被顺序的追加到文件中.

二、BufferedInputStream/BufferedOutputStream(高级流/处理流)(字节缓冲流)

1.缓冲流

java.io.BufferedOutputStream和BufferedInputStream.

缓冲流是一对高级流,作用是提高读写数据的效率.

缓冲流内部有一个字节数组,默认长度是8K.缓冲流读写数据时一定是将数据的读写方式转换为块读写来保证读写效率.

2.缓冲输出流写出数据时的缓冲区问题

通过缓冲流写出的数据会被临时存入缓冲流内部的字节数组,直到数组存满数据才会真实写出一次.

三、ObjectInputStream/ObjectInputStream(高级流/处理流)(对象输入/输出流)

1.对象流

java.io.ObjectOutputStream和ObjectInputSteam

对象流是一对高级流,在流连接中的作用是进行对象的序列化与反序列化。

对象序列化:将一个java对象按照其结构转换为一组字节的过程

对象反序列化:将一组字节还原为java对象(前提是这组字节是一个对象序列化得到的字节)

2.writeObject(Object obj)

对象输出流提供的独有方法:writeObject(Object obj) 该方法会进行对象序列化,并将序列化后的字节通过其连接的流写出. 序列化时要求该对象必须实现可序列化接口,否则会抛出异常: java.io.NotSerializableException

3.版本号serialVersionUID

当一个类实现了可序列化接口时,最好显式的定义下面的属性:serialVersionUID

即:序列化版本号

当对象输出流在进行对象序列化时,会查看是否有显式的版本号,如果没有 会根据当前类的结构计算版本号(当前类(这里是Person)的结构只要没有发生变化,那么无论 何时序列化版本号始终不会变化,只要改变过,那么序列化版本号一定会改变)并将该版本 号保存在序列化后的字节中.

重点: 当使用对象输入流反序列化时,对象输入流会检查要反序列化的对象与其对应的类(比如我们反序列化一个之前的Person对象) 的版本号是否一致,若不一致,则会抛出异常: java.io.InvalidClassException

比如OOSDemo序列化一个Person对象并写入文件person.obj后,我们在Person上添加一个新属性salary,此时Person类发生变化, 那么再使用OISDemo反序列化person.obj文件中之前序列化的对象时就会发生异常: InvalidClassException(因为Person类改变了结构,版本号不一致了)

如果后期修改了类的结构,又希望原来的对象还可以进行反序列化,则需要显式的定义出来序列化版本号,这样一来,当一个对象序列化后, 当前类结构改变了,只要版本号不变,那么之前的对象仍然可以进行反序列化.此时对象输入流会采取兼容方式,即: 能还原的属性都会进行还原,没有的属性则采用默认值.

4.transient

当一个属性被关键字transient修饰后,那么当进行对象序列化时,该属性的值会被忽略, 忽略不必要的属性可以达到对象"瘦身"的目的,提高程序响应速度,减少资源开销. 当然,反序列化时,该属性只会采用默认值

四、InputStreamReader/OutputStreamWriter(高级流/处理流)(字符流)

1.字符流

  • java将流按照读写单位划分为字节流与字符流.

  • java.io.InputStream和OutputStream是所有字节流的超类

  • 而java.io.Reader和Writer则是所有字符流的超类,它们和字节流的超类是平级关系.

  • Reader和Writer是两个抽象类,里面规定了所有字符流都必须具备的读写字符的相关方法.

  • 字符流最小读写单位为字符(char),但是底层实际还是读写字节,只是字符与字节的转换工作由字符流完成.

2.转换流

java.io.InputStreamReader和OutputStreamWriter

它们是字符流非常常用的一对实现类同时也是一对高级流,实际开发中我们不直接操作它们,但是它们在流连接中是非常重要的一环.

3.转换流的意义:

实际开发中我们还有功能更好用的字符高级流.但是其他的字符高级流都有一个共通点:不能直接连接在字节流上.而实际操作设备的流都是低级流同时也都是字节流.因此不能直接在流连接中串联起来.转换流是一对可以连接在字节流上的字符流,其他的高级字符流可以连接在转换流上.在流连接中起到"转换器"的作用(负责字符与字节的实际转换)

五、BufferedReader/PrintWriter(高级流/处理流)(字符流)

1.缓冲字符流

缓冲字符输出流:java.io.PrintWriter

java.io.BufferedWriter和BufferedReader

缓冲字符流内部也有一个缓冲区,读写文本数据以块读写形式加快效率.并且缓冲流有一个特别的功能:可以按行读写文本数据.

java.io.PrintWriter具有自动行刷新的缓冲字符输出流,实际开发中更常用.它内部总是会自动连接BufferedWriter作为块写加速使用.

2.PrintWriter的自动行刷新功能

如果实例化PW时第一个参数传入的是一个流,则此时可以再传入一个boolean型的参数,此值为true时就打开了自动行刷新功能。 即: 每当我们用PW的println方法写出一行字符串后会自动flush.

3.BufferedReader

缓冲字符输入流:java.io.BufferedReader

1):块读文本数据加速

2):可以按行读取字符串

4.缓冲字符输入流提供的读取一行字符串的方法:

String readLine()

该方法会连续读取若干字符,到换行符为止,然后将换行符之前的内容以一个字符串形式 返回。

注意:返回的字符串中不含有最后的换行符。

如果单独读取了空行(此行内容只有一个换行符,比如当前源代码中的第二行就是空行), 那么会返回一个空字符串。 当方法返回值为null时,表示流读取到了末尾。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值