IO,即输入(in)和输出(out),指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。Java 中是通过流处理 IO 的,
那么什么是流?
流(Stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中 “流” 动一样。
一般来说关于流的特性有下面几点:
IO 流主要的分类方式有以下 3 种:
输入与输出是相对于应用程序而言的,比如文件读写,读取文件是输入流,写文件是输出流,这点很容易搞反。
字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是 8 位的字节,字符流操作的是数据单元为 16 位的字符。
为什么要有字符流?
Java 中字符是采用 Unicode 标准,Unicode 编码中,一个英文为一个字节,一个中文为两个字节。而在 UTF-8 编码中,一个中文字符是 3 个字节。那么问题来了,如果使用字节流处理中文,如果一次读写一个字符对应的字节数就不会有问题,一旦将一个字符对应的字节分裂开来,就会出现乱码了。为了更方便地处理中文这些字符,Java 就推出了字符流。
字节流和字符流的其他区别?
常用的节点流
常用处理流(关闭处理流使用关闭里面的节点流)
缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter--- 增加缓冲功能,避免频繁读写硬盘。
转换流:InputStreamReader OutputStreamReader 实现字节流和字符流之间的转换。
数据流 DataInputStream DataOutputStream 等 - 提供将基础数据类型写入到文件中,或者读取出来.
流的关闭顺序
I/O 模型: 就是用什么样的通道或者说是通信模式和架构进行数据的传输和接收,很大程度上决定 了程序通信的性能。
Java 共支持 3 种网络编程的 I/O 模型: BIO、NIO、AIO 实际通信需求下,要根据不同的业务场景和性能需求决定选择不同的 I/O 模型。
同步并阻塞 (传统阻塞型),服务器实现模式为一个连接一个线程, 即客户端有连接请求时服务器 端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。
Java NIO : 同步非阻塞,服务器实现模式为一个线程处理多个请求 (连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/0 请求就进行处理。
Java AIO(NIO.2) : 异步 异步非阻塞,服务器实现模式为一个有效请求 - 个线程,客户端的 I/O 请 求都是由 OS 先完成了再通知服务器应用去启动线程进行处理,一般适用于连接数较多且连接时间 较长的应用
答:保存 (持久化) 对象及其状态到内存或者磁盘。
Java 平台允许我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时,这些对象才可能存在,即:这些对象的生命周期不会比 JVM 的生命周期更长。但在现实应用中,就可能要求在 JVM 停止运行之后能够保存 (持久化) 指定的对象,并在将来重新读取被保存的对象,Java 对象序列化就能够帮助我们实现该功能。
序列化对象将以字节数组的形式保存,所以静态成员不会被保存。使用 Java 对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的” 状态”,即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。
序列化对象实现远程数据传输
除了在持久化对象时会用到对象序列化之外,当使用 RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。Java 序列化 API 为处理对象序列化提供了一个标准机制,该 API 简单易用。
Serializable 实现序列化
在 Java 中,只要一个类实现了 java.io.Serializable 接口,那么它就可以被序列化。ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化。通过 ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化。writeObject 和 readObject 自定义序列化策略在类中增加 writeObject 和 readObject 方法可以实现自定义序列化策略。
序列化 ID
其实,这个序列化 ID 起着关键的作用,它决定着是否能够成功反序列化。简单来说,Java 的序列化机制是通过在运行时判断类的 serialVersionUID 来验证版本一致性的。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地实体类中的 serialVersionUID 进行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。
虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID),当 ID 一致时才可以被反序列化。
transient 关键字
Transient 关键字阻止该变量被序列化到文件中。
反序列化就是序列化的反向操作,将二进制的数据转换成对内存中对象的过程。