java nio详解

2025-04-14 22

// 来源:https://www.nzw6.comImage

Java NIO详解

解决方案

Java NIO(New Input/Output)是Java 1.4引入的一个新的I/O API,旨在提高I/O操作的性能。与传统的Java I/O相比,NIO提供了非阻塞I/O、通道(Channel)、缓冲区(Buffer)以及选择器(Selector)等功能。Java NIO的核心概念,并通过代码示例展示如何使用NIO进行文件读写、网络通信等操作。


1. Java NIO核心概念

Java NIO的主要特点是基于缓冲区和通道的操作模型。以下是几个关键概念:

  • Buffer(缓冲区):数据容器,用于存储不同类型的字节数据。
  • Channel(通道):用于在缓冲区和底层数据源(如文件或套接字)之间传输数据。
  • Selector(选择器):用于监听多个通道上的事件(如连接请求或数据到达)。
  • 非阻塞I/O:允许程序在等待I/O操作完成时继续执行其他任务。

2. 文件读写操作

2.1 使用FileChannel读取文件

以下是一个使用FileChannel读取文件内容的示例:

java
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;</p>

<p>public class FileReadExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("example.txt");
             FileChannel channel = fis.getChannel()) {</p>

<pre><code>        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while (channel.read(buffer) > 0) {
            buffer.flip(); // 切换到读模式
            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());
            }
            buffer.clear(); // 清空缓冲区以供下次写入
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

2.2 使用FileChannel写入文件

以下是一个使用FileChannel写入文件内容的示例:

java
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;</p>

<p>public class FileWriteExample {
    public static void main(String[] args) {
        try (FileOutputStream fos = new FileOutputStream("output.txt");
             FileChannel channel = fos.getChannel()) {</p>

<pre><code>        String content = "Hello, Java NIO!";
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.put(content.getBytes());
        buffer.flip(); // 切换到读模式
        channel.write(buffer);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}


3. 网络通信

3.1 使用SocketChannel实现客户端-服务器通信

3.1.1 服务器端代码

以下是一个简单的服务器端代码,使用ServerSocketChannel监听客户端连接:

java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;</p>

<p>public class NIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);</p>

<pre><code>    System.out.println("Server is listening on port 8080...");

    while (true) {
        SocketChannel socketChannel = serverSocketChannel.accept();
        if (socketChannel != null) {
            handleClient(socketChannel);
        }
    }
}

private static void handleClient(SocketChannel socketChannel) throws IOException {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int bytesRead = socketChannel.read(buffer);
    if (bytesRead > 0) {
        buffer.flip();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        String message = new String(data);
        System.out.println("Received: " + message);
        socketChannel.write(ByteBuffer.wrap("Message received".getBytes()));
    }
    socketChannel.close();
}

}

3.1.2 客户端代码

以下是一个简单的客户端代码,使用SocketChannel发送消息到服务器:

java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;</p>

<p>public class NIOClient {
    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 8080));</p>

<pre><code>    String message = "Hello from client!";
    socketChannel.write(ByteBuffer.wrap(message.getBytes()));

    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int bytesRead = socketChannel.read(buffer);
    if (bytesRead > 0) {
        buffer.flip();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        System.out.println("Server response: " + new String(data));
    }
    socketChannel.close();
}

}


4. 非阻塞I/O与多路复用

4.1 使用Selector实现多路复用

Selector是Java NIO中用于处理多个通道事件的核心类。以下是一个使用Selector监听多个客户端连接的示例:

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;
import java.util.Set;</p>

<p>public class SelectorExample {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);</p>

<pre><code>    System.out.println("Server is listening on port 8080...");

    while (true) {
        selector.select();
        Set<SelectionKey> selectedKeys = selector.selectedKeys();
        Iterator<SelectionKey> iterator = selectedKeys.iterator();

        while (iterator.hasNext()) {
            SelectionKey key = iterator.next();

            if (key.isAcceptable()) {
                handleAccept(key, selector);
            }

            if (key.isReadable()) {
                handleRead(key);
            }

            iterator.remove();
        }
    }
}

private static void handleAccept(SelectionKey key, Selector selector) throws IOException {
    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
    SocketChannel socketChannel = serverSocketChannel.accept();
    socketChannel.configureBlocking(false);
    socketChannel.register(selector, SelectionKey.OP_READ);
    System.out.println("New connection accepted.");
}

private static void handleRead(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int bytesRead = socketChannel.read(buffer);
    if (bytesRead > 0) {
        buffer.flip();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        System.out.println("Received: " + new String(data));
        socketChannel.write(ByteBuffer.wrap("Message received".getBytes()));
    }
    key.cancel();
    socketChannel.close();
}

}


5.

详细Java NIO的核心概念及其应用场景。通过文件读写、网络通信以及非阻塞I/O的示例代码,展示了Java NIO的强大功能。无论是处理大规模文件还是高并发网络通信,Java NIO都能提供高效的解决方案。希望能帮助你更好地理解和使用Java NIO!

1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!cheeksyu@vip.qq.com
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或教程,您可以投稿发布,成功分享后有积分奖励和额外收入!
5.严禁将资源用于任何违法犯罪行为,不得违反国家法律,否则责任自负,一切法律责任与本站无关

源码下载