导图社区 javaIO流
什么是javaIO流?想学习javaIO流吗?赶紧来点击这张图吧,这个是javaIO流的学习笔记,涵盖了基本要点,可以让你初步认识它哦,从而知道该从哪里入手学习javaIO流。同时,也欢迎各位同学补充这个笔记,方便更多的人认识和学习javaIO流。
编辑于2019-10-20 11:42:19JavaIO流
Input是读取数据,Output是写数据
数据源分为:源设备、目标设备。 1. 源设备:为程序提供数据,一般对应输入流。 2. 目标设备:程序数据的目的地,一般对应输出流。
读取文件经典写法
流的划分
IO流的体系
四大IO抽象类
文件字节流
FileInputStream通过字节的方式读取文件,适合读取所有类型的文件(图像、视频、文本文件等)。Java也提供了FileReader专门读取文本文件。 FileOutputStream 通过字节的方式写数据到文件中,适合所有类型的文件。Java也提供了FileWriter专门写入文本文件。
文件字符流
前面介绍的文件字节流可以处理所有的文件,但是字节流不能很好的处理Unicode字符,经常会出现“乱码”现象。所以,我们处理文本文件,一般可以使用文件字符流,它以字符为单位进行操作。
FileReader/FileWriter
缓冲字节流(普通文件)
Java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。 当对文件或者其他数据源进行频繁的读写操作时,效率比较低,这时如果使用缓冲流就能够更高效的读写信息。因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。 因此,缓冲流还是很重要的,我们在IO操作时记得加上缓冲流来提升性能。 BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率。
注意 1. 在关闭流时,应该先关闭最外层的包装流,即“后开的先关闭”。 2. 缓存区的大小默认是8192字节,也可以使用其它的构造方法自己指定大小。
缓冲字符流(文本文件)
BufferedReader/BufferedWriter增加了缓存机制,大大提高了读写文本文件的效率,同时,提供了更方便的按行读取的方法:readLine(); 处理文本时,我们一般可以使用缓冲字符流。
注意 1. readLine()方法是BufferedReader特有的方法,可以对文本文件进行更加方便的读取操作。 2. 写入一行后要记得使用newLine()方法换行。
字节数组流
ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况! 说白了,FileInputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的”某个字节数组对象”当做数据源。
数据流(java基本数据类型)
数据流将“基本数据类型与字符串类型”作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。 DataInputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型数据(如:int、double、String等)的方法。 DataInputStream和DataOutputStream是处理流,可以对其他节点流或处理流进行包装,增加一些更灵活、更高效的功能。
菜鸟雷区 使用数据流时,读取的顺序一定要与写入的顺序一致,否则不能正确读取数据。
对象流
我们前边学到的数据流只能实现对基本数据类型和字符串类型的读写,并不能读取对象(字符串除外),如果要对某个对象进行读写操作,我们需要学习一对新的处理流:ObjectInputStream/ObjectOutputStream。 ObjectInputStream/ObjectOutputStream是以“对象”为数据源,但是必须将传输的对象进行序列化与反序列化操作。
注意 1. 对象流不仅可以读写对象,还可以读写基本数据类型。 2. 使用对象流读写对象时,该对象必须序列化与反序列化。 3. 系统提供的类(如Date等)已经实现了序列化接口,自定义类必须手动实现序列化接口。
转换流(控制台输入输出)
InputStreamReader/OutputStreamWriter用来实现将字节流转化成字符流。比如,如下场景: System.in是字节流对象,代表键盘的输入,如果我们想按行接收用户的输入时,就必须用到缓冲字符流BufferedReader特有的方法readLine(),但是经过观察会发现在创建BufferedReader的构造方法的参数必须是一个Reader对象,这时候我们的转换流InputStreamReader就派上用场了。 而System.out也是字节流对象,代表输出到显示器,按行读取用户的输入后,并且要将读取的一行字符串直接显示到控制台,就需要用到字符流的write(String str)方法,所以我们要使用OutputStreamWriter将字节流转化为字符流。
序列化和反序列化
当两个进程远程通信时,彼此可以发送各种类型的数据。 无论是何种类型的数据,都会以二进制序列的形式在网络上传送。比如,我们可以通过http协议发送字符串信息;我们也可以在网络上直接发送Java对象。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象才能正常读取。 把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。
对象序列化的作用有如下两种: 1. 持久化: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中,比如:休眠的实现。以后服务器session管理,hibernate将对象持久化实现。 2. 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。
序列化和发序列化
注意 1. static属性不参与序列化。 2. 对象中的某些属性如果不想被序列化,不能使用static,而是使用transient修饰。 3. 为了防止读和写的序列化ID不一致,一般指定一个固定的序列化ID。
// 通过ObjectOutputStream将Person对象的数据写入到文件中,即序列化。
// 通过ObjectInputStream将文件中二进制数据反序列化成Person对象:
装饰者模式
装饰器模式是GOF23种设计模式中较为常用的一种模式。它可以实现对原有类的包装和装饰,使新的类具有更强的功能。 我这里有智能手机iphone, 我们可以通过加装投影组件,实现原有手机功能的扩展。这就是一种“装饰器模式”。 我们在未来给普通人加装“外骨骼”装饰,让普通人具有力扛千斤的能力,也是一种“装饰器模式”。
IO流中的装饰者模式
IO流有关工具类(Apache开源包)
FileUtils
IOUtils