• 节点流:直接和设别,特定地方读写
  • 过滤流:(装饰器模式)节点流作为输入或者输出,使用一个存在的输入或者输出流来创建(作为参数传递进去)

IO流的链:数据–》缓冲输出流–》文件输出流–》文件。装饰器模式的作用,获取一个

装饰器模式

NIO–面向块或者缓冲区编程

1.4出来的

NIO组件回顾

Java NIO,它不仅仅可以用在网络编程中,还能用在文件读写等其它场景

Channel–桥梁

java.nio.channels.Channel

实体之间的桥梁,实体可以是硬件设备,文件,网络套接字或者可执行IO操作的程序(Linux中一切皆文件)

不同实体(文件)类型对应不同的类型的Channel:

  • FileChannel : 操作普通文件
  • DatagramChannel:UDP协议
  • SocketChannel:TCP协议,客户端和服务端之间的Channel
  • ServerSocketChannel:TCP协议,用于服务端的Channel

Buffer–数据容器

线性有序序列(数组),存储特定的基本类型。Buffer的类型有CharBuffer,ByteBuffer, ShortBuffer, IntBuffer, LongBUffer, FloatBuffer, DoubleBuffer这7个,没有boolean,对于每一种都有堆内存和直接内存的实现****。(HeapByteBuffer和DirectByteBuffer)

两种模式:读模式和写模式

主要属性:是capacity(读模式和写模式一致,从1开始),limit(读模式表示最大可读到的位置,写模式是可以写到的最大位置,从1开始),position(读模式是下一个可读的位置,写模式是下一个可写的位置。从0开始)。

和Channel的关系:从buffer读取数据到Channel里面,从Channel读取数据到buffer里面

重要的API:

  • 分配一个Buffer:allocate()
  • 写入数据:buf.put() 或者 channel.read(buf) ,read是read to buffer的意思
  • 切换为读模式:buf.flip()Buffer从写模式切换为读模式的时候。limit变成position的值,position变成0
  • 读取数据:buf.read() 或者 channel.write(buf),write 是 write from buf
  • 重新读取和写入:rewind() ,重置 position 为0,limit 和 capacity 保持不变,可以重新读写数据
  • 清空数据:buf.clear() 清空数据
  • 压缩数据:buf.compact() 清除已读数据,将未读数据往前移动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.deltaqin.io;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

/**
* @author deltaqin
* @date 2021/4/15 12:55 下午
*/
public class FileChannelDemo {
public static void main(String[] args) throws IOException {
FileChannel fileChannel = new RandomAccessFile("a.txt", "rw").getChannel();
// Byte类型的buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);

while ((fileChannel.read(buffer)) != -1) {
// buffer 默认是写模式,flip 是切换为读模式
buffer.flip();
// buffer是否有数据未读取
while (buffer.hasRemaining()) {
// 未读取数据的长度
int remain = buffer.remaining();
byte[] bytes = new byte[remain];
//读出buffer的数据
buffer.get(bytes);
System.out.println(new String(bytes, StandardCharsets.UTF_8));
}
// 清空buffer,为下一次数据写入准备。将buffer切换为写模式
buffer.clear();
}
}
}

DirectByteBuffer

ByteBuffer buffer = ByteBuffer.allocateDirect__(512);