写点什么

IO

用户头像
ltc
关注
发布于: 2021 年 05 月 24 日

IO 流的特点

流(Stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。

  1. 先进先出:最先写入输出流的数据最先被输入流读取到。

  2. 顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile除外)

  3. 只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

IO 流分类

  • 按数据流的方向:输入流、输出流

  • 按处理数据单位:字节流、字符流

  • 按功能:节点流、处理流

字节流和字符流的其他区别

  1. 字节流一般用来处理图像、视频、音频、PPT、Word 等类型的文件。字符流一般用于处理纯文本类型的文件,如 TXT 文件等,但不能处理图像视频等非文本文件。用一句话说就是:字节流可以处理一切文件,而字符流只能处理纯文本文件。

  2. 字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。

缓冲流效率一定高吗

不一定,要看具体的使用场景: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。


用户头像

ltc

关注

ltc 2019.07.04 加入

还未添加个人简介

评论

发布
暂无评论
IO