1.IO流整体结构图(图片为转载)
2.使用场合推荐
纯文本文件适合用字符流
图片,视频,音频等二进制文件推荐用字节流
不管什么都可以用字节流
3.字节流和字符流基类及其子类
字节输入流:InputStream 子类: 文件输入流 :FileInputStream 字节缓冲输入流:BueredInputStream
字节输出流:OutputStream 子类: 文件输出流:FileOutPutStream 字节缓冲输出流:
BueredOutputStream
字符输入流:Reader 子类: 文件输入流:FileReader 转换流:InputStreamReader
字符缓冲输入流 BufferedReader
字符输出流: Writer 子类 : 文件输出流: FileWriter 转换流:OutputStreamWriter
字符缓冲输出流:BufferedWriter
缓冲区的工作原理
读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量最后一次性写出去,减少了读写次数,提高了效率 缓冲流内部提供了一个默认大小为8192(8kb)的缓冲区
1.字节缓冲流介绍
BufferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
2.字符缓冲流介绍
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
对象序列化流
对象序列化介绍
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
对象序列化流: ObjectOutputStream
将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
注意事项
一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口,Serializable是一个标记接口,实现该接口,不需要重写任何方法
//ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
//创建对象
Student s = new Student("林青霞",30);
//void writeObject(Object obj):将指定的对象写入ObjectOutputStream
oos.writeObject(s);
//释放资源
oos.close();
}
5.对象反序列化流
对象反序列化流: ObjectInputStream
ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
//ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
//Object readObject():从ObjectInputStream读取一个对象
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
6.serialVersionUID&transient
serialVersionUID
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常
如果出问题了,如何解决呢?
重新序列化
给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42L;
transient:
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
Properties类
java中提供了配置文件的操作类Properties类(java.util.Properties):
public class Properties extends Hashtable.可见Properties类继承了Hashtable,而HashTable又实现了Map接口,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。
Properties的常用方法:
1.setProperty(String key, String value)
调用 Hashtable 的方法 put。
2.
getProperty(String key)
用指定的键在此属性列表中搜索属性
3.
getProperty(String key, String defaultValue)
用指定的键在属性列表中搜索属性。
4.
load(InputStream inStream)
从输入流中读取属性列表(键和元素对)。
5.
load(Reader reader)
按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
下面我们来了解一下AIO,NIO,BIO
首先我们需要了解同步和异步,阻塞和非阻塞
序列化就是将对象保存到磁盘中或者在网络中传输,使用一个字节序列表示对象
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
同步与异步
-
同步: 同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。
-
异步: 异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果,此时我们可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者其返回结果。
-
同步和异步的区别最大在于异步的话调用者不需要等待处理结果,被调用者会通过回调等机制来通知调用者其返回结果。
-
阻塞和非阻塞
-
阻塞: 阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当条件就绪才能继续。
-
非阻塞: 非阻塞就是发起一个请求,调用者不用一直等着结果返回,可以先去干其他事情。
BIO
同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。服务器实现一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,没处理完之前此线程不能做其他操作(如果是单线程的情况下,我传输的文件很大呢?),当然可以通过线程池机制改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO
:同步非阻塞,服务器实现一个连接一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4之后开始支持。
AIO
AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由操作系统先完成了再通知服务器应用去启动线程进行处理,AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用操作系统参与并发操作,编程比较复杂,JDK1.7之后开始支持。.
AIO属于NIO包中的类实现,其实IO主要分为BIO和NIO,AIO只是附加品,解决IO不能异步的实现
BIO:线程发起IO请求到IO结束,线程一直阻塞,直到操作完成。
NIO:线程发起IO请求,立即返回,期间可以做其他事;当内核有可用IO资源时,通过调用注册的回调函数通知线程做IO操作,线程开始阻塞,直到操作完成。
AIO:线程发起IO请求,立即返回;内存做好IO操作的准备之后,做IO操作,直到操作完成或者失败,通过调用注册的回调函数通知线程做IO操作完成或者失败。