博客
关于我
NIO知识点简单记录一
阅读量:304 次
发布时间:2019-03-03

本文共 3245 字,大约阅读时间需要 10 分钟。

NIO简介

NIO(Non-Blocking I/O)是Java NIO(I/O操作)模型的一大改进,旨在提高数据输入输出操作的效率。与传统的同步I/O模型不同,NIO采用非阻塞方式,允许多个I/O操作同时进行,充分发挥了多核处理器的性能优势。

NIO与传统IO的主要区别在于操作方式:

  • NIO:支持多个操作同时进行,适合处理大量数据。
  • 传统IO:操作是串行执行的,效率较低。

NIO引入了通道(Channel)缓冲区(Buffer),优化了数据传输和处理流程。

NIO中的缓冲区

缓冲区是NIO中核心概念,用于临时存储数据,提升读写效率。缓冲区分为不同类型(如ByteBuffer、CharBuffer等),根据数据类型选择合适的缓冲区。缓冲区操作通过`put()`和`get()`方法完成,缓冲区属性包括`capacity`(容量)、`limit`(界限)、`position`(当前位置)和`mark`(标记)。

缓冲区的核心属性关系:

0 ≤ position ≤ limit ≤ capacity
缓冲区属性可动态调整,但容量固定。

NIO直接缓冲区与非直接缓冲区

缓冲区分为直接和非直接两种类型: - **直接缓冲区**:通过`allocate()`方法分配,缓冲区位于JVM内存中。 - **非直接缓冲区**:通过`allocateDirect()`方法分配,缓冲区直接映射到物理内存。

直接缓冲区适合需要高性能的场景,但可能导致内存泄漏;非直接缓冲区更安全,但性能略低。

NIO通道(Channel)的原理与获取

通道是NIO中处理数据传输的核心组件,与缓冲区配合使用。通道负责数据的读写,实现多线程、异步I/O操作。通道不存储数据,需配合缓冲区进行数据传输。

文件操作实例

以下是基于NIO完成的文件操作示例:

1. 使用非直接缓冲区复制JPG照片

File input = new File("input.jpg");  
File output = new File("output.jpg");
ByteBuffer inputBuffer = ByteBuffer.allocateDirect(1024);
ByteBuffer outputBuffer = ByteBuffer.allocateDirect(1024);
FileChannel inputChannel = FileChannel.open(input, StandardOpenOption.READ);
FileChannel outputChannel = FileChannel.open(output, StandardOpenOption.WRITE);
while (inputBuffer.hasRemaining() && outputBuffer.hasRemaining()) {
int read = inputChannel.read(inputBuffer);
if (read == -1) break;
int written = outputChannel.write(outputBuffer);
if (written == -1) break;
}
inputBuffer.clear();
outputBuffer.clear();
inputChannel.close();
outputChannel.close();
inputBuffer.close();
outputBuffer.close();

2. 使用直接缓冲区复制JPG照片

File input = new File("input.jpg");  
File output = new File("output.jpg");
MappedByteBuffer inputBuffer = Files.mapByteBuffer(input, 0, 1024);
MappedByteBuffer outputBuffer = Files.mapByteBuffer(output, 1024, 1024);
FileChannel inputChannel = FileChannel.open(input, StandardOpenOption.READ);
FileChannel outputChannel = FileChannel.open(output, StandardOpenOption.WRITE);
while (inputBuffer.hasRemaining() && outputBuffer.hasRemaining()) {
long read = inputChannel.read(inputBuffer);
if (read == -1) break;
long written = outputChannel.write(outputBuffer);
if (written == -1) break;
}
inputBuffer.clear();
outputBuffer.clear();
inputChannel.close();
outputChannel.close();
inputBuffer.close();
outputBuffer.close();

3. 通道间数据传输(直接缓冲区)

CompletionHandler
handler = (v, t) -> System.out.println("文件已复制");
File inputFile = new File("input.txt");
File outputFile = new File("output.txt");
FileChannel inputChannel = FileChannel.open(inputFile, StandardOpenOption.READ);
FileChannel outputChannel = FileChannel.open(outputFile, StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.POSIX);
ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
while (true) {
int read = inputChannel.read(buffer);
if (read == -1) break;
int written = outputChannel.write(buffer);
if (written == -1) break;
buffer.flip();
outputChannel.read(buffer, 0, buffer.capacity(), handler);
buffer.clear();
}
inputChannel.close();
outputChannel.close();
buffer.clear();

分散读取与聚集写入

分散读取和聚集写入是NIO中的高级特性,适合处理大文件或多线程环境: - **分散读取**:将通道数据分散到多个缓冲区,提升并行读取效率。 - **聚集写入**:将多个缓冲区数据聚集到通道,优化写入性能。

通过合理配置缓冲区和使用分散读取/聚集写入,可以充分发挥NIO的优势,提升数据操作效率。

转载地址:http://puql.baihongyu.com/

你可能感兴趣的文章
nodejs服务端实现post请求
查看>>
nodejs框架,原理,组件,核心,跟npm和vue的关系
查看>>
Nodejs概览: 思维导图、核心技术、应用场景
查看>>
nodejs模块——fs模块
查看>>
Nodejs模块、自定义模块、CommonJs的概念和使用
查看>>
nodejs生成多层目录和生成文件的通用方法
查看>>
nodejs端口被占用原因及解决方案
查看>>
Nodejs简介以及Windows上安装Nodejs
查看>>
nodejs系列之express
查看>>
nodejs系列之Koa2
查看>>
Nodejs连接mysql
查看>>
nodejs连接mysql
查看>>
NodeJs连接Oracle数据库
查看>>
nodejs配置express服务器,运行自动打开浏览器
查看>>
NodeMCU教程 http请求获取Json中文乱码解决方案
查看>>
Nodemon 深入解析与使用
查看>>
NodeSession:高效且灵活的Node.js会话管理工具
查看>>
node~ http缓存
查看>>
node不是内部命令时配置node环境变量
查看>>
node中fs模块之文件操作
查看>>