I/O
I/O
什么是I/O
I/O
就是Input
和 Output
的缩写,常见的有文件IO,网络IO,设备IO 等。在linux中所有的组成元素都是一个文件,在文件对于内存来说就是一种流的表现形式。对文件的操作就是对数据流的读写操作,这些读取文件中数据 叫Input流
,主要操作 read
函数,往文件中写叫Output流
,主要操作 write
函数。
主要概念
1 阻塞和非阻塞
阻塞
是指数据请求方在请求数据时,被请求方准备完数据的时候系统调用会一直处于等待状态,非阻塞
是指如果被请求方未准备好数据。请求方调用会立即返回,等待完成的信号时再去读取数据。
2 同步与异步
同步
是指数据请求方从发起请求到完成整个数据完成时,该请求不会返回,一旦调用返回,请求就结束了,异步
是指数据请求方发起指令后就返回,等到被请求方将数据处理好后,再通知到数据的请求方,整个数据 的等待和处理都是被请求一方处理的。
3 I/O 模型
同步阻塞
数据请求方调用请求时 一直等待着返回,直到数据通过原请求返回结束同步非阻塞
数据请求方调用请求时 ,先做其他请求,每过一段时间会观察是否有返回异步堵塞
数据请求方调用请求时 一直等待着返回 ,被请求方完成护理后通过回调等方式通知请求方结果异步非堵塞
数据请求方调用请求时,先做其他请求,被请求方完成护理后通过回调等方式通知请求方结果
传统I/O
InputStream
主要class FileInputStream
ByteArrayInputSteam``SocketInputStream`` BufferInputStream
读取操作
1 | InputStream is = new FileInputStream("../ad/text.txt") |
OutputStream
主要class FileOuputStream
ByteArrayOuputSteam
写入操作
1 | OutputStream os = new FileOuputStream("../ad/text.txt") |
NI/O
简介
java non-blocking IO
是用来替代传统 IO 的一个方案,可以实现非阻塞式
IO模型
主要是由 Channels
、Buffers
和 Selectors
组成。
Channels
有点类似传统IO 的流主要有以下几个区别
channel
可以同时读写,但传统IO流只能单向流动channel
可以进行异步的读写channel
的读写强制使用buffer
主要实现class- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
Buffers
使用 channle
必定用到buffers
,将数据写入到缓冲区时候,缓冲区会记录已经写了多少数据,一但要读取数据的时候 调用filp
函数将缓冲区从写入模式改成读取模式,读取后需要用clear
或者 compact
函数来清除或者局部清除缓冲区。
Selectors
可以对多个 channel
通道进行监听和处理,通道必须处于非阻塞模式 non-blocking mode
使用简介
读取操作
1 | RandomAccessFile file = new RandomAccessFile("demo.txt", "rw") |
写入操作
1 | RandomAccessFile file = new RandomAccessFile("demo.txt", "r"); |
okio
简介
对传统IO的一层封装,让传统IO更加好用
Sink
Sink
对应传统IO的 OutputStream
主要代码
1
2
3
4
5
6
7
8
9
10
11
12 actual interface Sink : Closeable, Flushable {
actual fun write(source: Buffer, byteCount: Long)
actual override fun flush()
actual fun timeout(): Timeout
actual override fun close()
}
Source
Source
对应传统IO的 IntputSteam
主要代码
1 | interface Source : Closeable { |
使用简介
读取操作
1 | Source fileSource = Okio.source(new File("demo.txt")) |
写入操作
1 | Sink sink = Okio.sink(new File("demoCopyOkio.txt")); |