-
java.io 中最为核心的一个概念是流(Stream),面向流的编程.java 中,一个流要么是输入流,要么是输出流,
-
不可能同时是输入流又是输出流
-
java,nio 中拥有 3 个核心概念:Selector,Channel 与 Buffer,在 java.nio 中,我们是面向块(block)
-
或是缓冲区(Buffer)编程的 . Buffer 本身就是一块内存,底层实现上,它实际上是个数组.数据的读写都是通过 Buffer 来实现的
-
除了数组之外,Buffer 还提供了对于数据的结构化访问方式,并且可以追踪到系统的读写过程
-
java 中的 8 中原生数据类型都有各自对应的 Buffer 类型 ,比如: IntBuffer,ByteBuffer…
-
Channel 指的是可以向其写入数据或是从中读取数据的对象,它类似于 java.io 中的 Stream
-
所有数据的读写都是通过 Buffer 类进行的,永远不会出现直接向 Channel 写入数据的情况,或是直接从 Channel读取数据的情况
-
与 Stream 不同的是,Channel 是双向的,一个流只可能是 InputStream 或是 OutputStream,Channel打开后
-
则可以j进行读取,写入或者读写
-
由于 Channel 是双向的,因此它能更好的反映出底层操作系统的真实情况;在 Linux 系统中,底层操作系统的通道就是双向的
实例一:
IntBuffer buffer = IntBuffer.allocate(10);
for (int i = 0; i < buffer.capacity(); i++) {
int randomNumber = new SecureRandom().nextInt(20);
buffer.put(randomNumber);
}
buffer.flip();
while (buffer.hasRemaining()) {
System.out.println(buffer.get());
}
实例二:
FileInputStream fileInputStream = new FileInputStream("NioTest2.txt");
FileChannel fileChannel = fileInputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
int read = fileChannel.read(byteBuffer);
// 操作反转 读->写
byteBuffer.flip();
while (byteBuffer.remaining() > 0) {
byte b = byteBuffer.get();
System.out.println("Character : " + (char) b);
}
fileChannel.close();
实例三:
FileOutputStream fileOutputStream = new FileOutputStream("NioTest3.xtx");
FileChannel fileChannel = fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
byte[] message = "xwy,hello".getBytes();
for (int i = 0; i < message.length; i++) {
byteBuffer.put(message[i]);
}
byteBuffer.flip();
fileChannel.write(byteBuffer);
fileChannel.close();
关于 NIO Buffer 中的 3 个重要属性的含义:position,limit,capacity
0 <= mark <= position <= limit <= capacity
buffer.flip();
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
通过 NIO 读取文件涉及到 3 个步骤:
- 从 FIleInputStream 获取到 FileChannel 对象
- 创建 Buffer
- 将数据从 Channel 读取到 Buffer 中
绝对方法与相对方法的含义:
- 相对方法:limit 值与 position 值会在操作时被考虑到
- 绝对方法:完全忽略掉 limit 值与 position 值
只读 buffer:可以随时将一个普通 buffer 调用 asReadOnlyBuffer 方法返回一个只读buffer,但不能将一个只读 buffer 转换成为读写 buffer