NIO的使用

以下是一个NIO的例子,这里比作是一个送货的比喻,一下文字简介:

1.送什么货物:FileInputStream fis = new FileInputStream("C:\\reset.css");

2.货物送到哪里:FileOutputStream fos = new FileOutputStream("D:\\reset.css");

3.需要接收货物的快递员:FileChannel fisChannel = fis.getChannel();

4.到达目的城市需要快递员送到手里:FileChannel fosChannel = fos.getChannel();

5.需要车辆来承载这些货物,定义这个车一下能装多少货物:ByteBuffer buffer = ByteBuffer.allocate(1024);

6.执行需要的元素,每次送完一车那么把这车标为空车:buffer.flip();

7.当装不满一车代表不用再接收和送了:if(num == -1)

8.通知快递员下班或者干其他的:fisChannel.close();fosChannel.close();


### Java NIO 使用教程 Java NIO(New I/O)是 Java 1.4 引入的一组新的 I/O API,相较于传统的 Java IO API,NIO 提供了更高效的 I/O 操作方式,尤其适用于高并发、大数据量的场景。Java NIO 的核心组件包括 **Channel**、**Buffer** 和 **Selector**。 #### Channel 与 Buffer 的基本使用 Java NIO 中的数据读写操作是通过 **Channel** 和 **Buffer** 完成的。Channel 类似于传统的流(Stream),但支持双向数据传输(既可读也可写),而 Buffer 是用于存储数据的容器。 以下是一个使用 NIO 从文件中读取数据的示例: ```java import java.io.FileInputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class TestChannelRead { public static void main(String[] args) throws Exception { FileInputStream fileInputStream = new FileInputStream("D:\\test.txt"); FileChannel fileChannel = fileInputStream.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); fileChannel.read(buffer); buffer.flip(); while (buffer.hasRemaining()) { byte b = buffer.get(); System.out.print((char) b); } fileInputStream.close(); } } ``` 在上述代码中,`FileChannel` 用于从文件中读取数据,`ByteBuffer` 是用于存储数据的缓冲区。通过 `read()` 方法将数据读入缓冲区,随后调用 `flip()` 方法切换缓冲区的读写模式,最后逐字节读取并输出内容[^3]。 #### Buffer 的类型与操作 Java NIO 提供了多种 Buffer 类型,包括 `ByteBuffer`、`CharBuffer`、`DoubleBuffer`、`FloatBuffer`、`IntBuffer`、`LongBuffer` 和 `ShortBuffer`。其中 `ByteBuffer` 是最常用的类型,支持直接内存分配的 `DirectByteBuffer`,在大数据量传输时性能更优,因为它绕过了 JVM 堆内存,减少了数据在用户空间和内核空间之间的复制[^2]。 缓冲区的基本操作包括: - `allocate(int capacity)`:分配缓冲区空间 - `put()`:将数据写入缓冲区 - `flip()`:切换为读模式,设置 `limit` 为当前 `position`,并将 `position` 重置为 0 - `get()`:从缓冲区读取数据 - `clear()` 或 `compact()`:清空或压缩缓冲区,准备下一次写入 #### 文件写入操作 Java NIO 同样支持高效的文件写入操作。以下是一个将字符串写入文件的示例: ```java import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class TestChannelWrite { public static void main(String[] args) throws Exception { FileOutputStream fileOutputStream = new FileOutputStream("D:\\output.txt"); FileChannel fileChannel = fileOutputStream.getChannel(); String data = "Hello, Java NIO!"; ByteBuffer buffer = ByteBuffer.wrap(data.getBytes()); fileChannel.write(buffer); fileOutputStream.close(); } } ``` 该代码通过 `FileChannel` 将字符串数据写入指定文件,使用 `ByteBuffer.wrap()` 方法将字符串转换为字节缓冲区,并通过 `write()` 方法完成写入操作[^3]。 #### 文件锁定与并发控制 Java NIO 支持文件锁定功能,可用于多线程或跨进程的并发控制。以下是一个使用文件锁的示例: ```java import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; public class FileLockExample { public static void main(String[] args) throws Exception { RandomAccessFile file = new RandomAccessFile("D:\\lock.txt", "rw"); FileChannel channel = file.getChannel(); // 获取文件锁 FileLock lock = channel.lock(); // 写入数据 String data = "Locked content."; channel.write(ByteBuffer.wrap(data.getBytes())); // 释放锁 lock.release(); file.close(); } } ``` 在此示例中,`FileLock` 用于锁定整个文件,防止其他进程或线程同时修改文件内容,从而确保数据一致性[^4]。 #### 分散与聚集读取 Java NIO 支持分散(Scattering)和聚集(Gathering)读写操作,允许一次从多个 Buffer 读取数据或将数据写入多个 Buffer。这种方式特别适用于处理结构化数据。 以下是一个使用 `ScatteringByteChannel` 的示例: ```java import java.io.FileInputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class ScatteringRead { public static void main(String[] args) throws Exception { FileInputStream fileInputStream = new FileInputStream("D:\\data.txt"); FileChannel channel = fileInputStream.getChannel(); ByteBuffer header = ByteBuffer.allocate(10); ByteBuffer body = ByteBuffer.allocate(20); channel.read(new ByteBuffer[]{header, body}); header.flip(); body.flip(); System.out.println("Header: " + new String(header.array())); System.out.println("Body: " + new String(body.array())); fileInputStream.close(); } } ``` 此示例中,`read()` 方法将数据分散读取到两个缓冲区中,分别用于处理不同的数据段[^4]。 #### 网络编程中的 NIO Java NIO 在网络编程中也提供了强大的支持,尤其是通过 `Selector` 实现的多路复用机制,可以高效地管理多个连接。 以下是一个简单的 NIO TCP 服务器示例: ```java import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; public class NioServer { public static void main(String[] args) throws IOException { Selector selector = Selector.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress("localhost", 8080)); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { int readyChannels = selector.select(); if (readyChannels == 0) continue; Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); SocketChannel clientChannel = serverChannel.accept(); clientChannel.configureBlocking(false); clientChannel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel clientChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(256); int bytesRead = clientChannel.read(buffer); if (bytesRead > 0) { buffer.flip(); clientChannel.write(buffer); } else if (bytesRead == -1) { clientChannel.close(); } } keyIterator.remove(); } } } } ``` 该服务器使用 `Selector` 监听多个连接事件,并通过 `SocketChannel` 进行非阻塞读写操作,适用于高并发场景。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值