IO
IO 流的特点
流(Stream
),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。
先进先出:最先写入输出流的数据最先被输入流读取到。
顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(
RandomAccessFile
除外)只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。
IO 流分类
按数据流的方向:输入流、输出流
按处理数据单位:字节流、字符流
按功能:节点流、处理流
字节流和字符流的其他区别
字节流一般用来处理图像、视频、音频、PPT、Word 等类型的文件。字符流一般用于处理纯文本类型的文件,如 TXT 文件等,但不能处理图像视频等非文本文件。用一句话说就是:字节流可以处理一切文件,而字符流只能处理纯文本文件。
字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。
缓冲流效率一定高吗
不一定,要看具体的使用场景:FileOutputStream 的 write(byte[] buf)和 BufferedOutputStream 的 write(byte[] buf)的效率差不多,因为他们的底层调用的方法是一样的。
缓冲流体现了 Java 中的哪种设计模式思想
装饰器模式
为什么要实现序列化
把对象的字节序列永久地保存到磁盘上。(持久化对象)
可以将 Java 对象以字节序列的方式在网络中传输。(网络传输对象)
如何实现序列化
如果要让某个对象支持序列化机制,则其类必须实现下面这两个接口中任一个:
Serializable
Externalizable
序列化数据后,再次修改类文件,读取数据会出问题,如何解决呢
每个可以序列化的类里面都会存在一个serialVersionUID
,只要这个值前后一致,即使类升级了,系统仍然会认为他们是同一版本。如果我们不显式指定一个,系统就会使用默认值。
我们应该总是显式指定一个版本号,这样做的话我们不仅可以增强对序列化版本的控制,而且也提高了代码的可移植性。因为不同的 JVM 有可能使用不同的策略来计算这个版本号,那样的话同一个类在不同的 JVM 下也会认为是不同的版本。
如何维护这个版本号呢
只修改了类的方法,无需改变 serialVersionUID;
只修改了类的 static 变量和使用 transient 修饰的实例变量,无需改变 serialVersionUID;
如果修改了实例变量的类型,例如一个变量原来是 int 改成了 String,则反序列化会失败,需要修改 serialVersionUID;如果删除了类的一些实例变量,可以兼容无需修改;如果给类增加了一些实例变量,可以兼容无需修改,只是反序列化后这些多出来的变量的值都是默认值。
不想进行序列化的成员变量怎么办
使用 transient 关键字声明不需要序列化的成员变量
Linux 环境下的 network IO 分几种模式
blocking IO
nonblocking IO
IO multiplexing
signal driven IO
asynchronous IO
Linux network IO 发生时涉及的对象和步骤
对于一个 network IO (这里我们以 read 举例),它会涉及到两个系统对象,一个是调用这个 IO 的 process (or thread),另一个就是系统内核(kernel)。当一个 read 操作发生时,它会经历两个阶段:
等待数据准备 (Waiting for the data to be ready)
将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
blocking IO
在 linux 中,默认情况下所有的 socket 都是 blocking 的。
non-blocking IO
Linux 下,可以通过设置 socket 使其变为 non-blocking。
IO multiplexing
在 IO multiplexing Model 中,实际中,对于每一个 socket,一般都设置成为 non-blocking,但是,如上图所示,整个用户的 process 其实是一直被 block 的。只不过 process 是被 select 这个函数 block,而不是被 socket IO 给 block。
Asynchronous I/O
各个 IO Model 的比较如图所示
blocking 和 non-blocking 的区别在哪
调用 blocking IO 会一直 block 住对应的进程直到操作完成,而 non-blocking IO 在 kernel 还准备数据的情况下会立刻返回。
synchronous IO 和 asynchronous IO 的区别在哪
两者的区别就在于 synchronous IO 做”IO operation”的时候会将 process 阻塞。按照这个定义,之前所述的 blocking IO,non-blocking IO,IO multiplexing 都属于 synchronous IO。定义中所指的”IO operation”是指真实的 IO 操作,就是 recvfrom 这个 system call。
评论