Java IO与NIO的对比与高级用法

在Java中,I/O操作(输入/输出操作)是非常基础且重要的一部分。Java提供了两种主要的I/O API:传统的IO(java.io包)和新IO(NIO,java.nio包)。这两者在设计理念、性能和使用场景上有显著的不同。本文将深入探讨Java IO与NIO的对比,并提供一些高级用法的示例代码。

1. Java IO与NIO的基本概念
1.1 Java IO

Java IO API是基于流(Stream)的模型。它以同步和阻塞的方式进行数据读写操作。每次I/O操作都会阻塞调用线程,直到操作完成。这种方式简单直观,但在高并发场景下性能表现不佳。

1.2 Java NIO

Java NIO(Non-blocking IO)引入了一种基于缓冲区(Buffer)和通道(Channel)的模型。NIO支持非阻塞模式,可以在进行I/O操作时不中断线程,从而提高了性能和可扩展性。NIO还引入了选择器(Selector)用于管理多个通道的非阻塞I/O操作。

2. Java IO与NIO的对比
特性Java IOJava NIO
模型基于流 (Stream)基于缓冲区 (Buffer) 和通道 (Channel)
阻塞/非阻塞阻塞I/O非阻塞I/O
数据处理字节/字符流缓冲区中读取和写入数据
性能简单,但在高并发下性能较差在高并发和大数据处理场景下性能更佳
API复杂度较为简单复杂度较高
3. Java IO的高级用法
3.1 文件读写操作
import java.io.*;

public class FileIODemo {
    public static void main(String[] args) {
        String filePath = "example.txt";
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write("Hello, Java IO!");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
3.2 网络通信(Socket编程)
import java.io.*;
import java.net.*;

public class SocketIODemo {
    public static void main(String[] args) {
        // Server
        new Thread(() -> {
            try (ServerSocket serverSocket = new ServerSocket(8080)) {
                Socket socket = serverSocket.accept();
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                writer.println("Hello, Client!");
                System.out.println("Client says: " + reader.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        // Client
        new Thread(() -> {
            try (Socket socket = new Socket("localhost", 8080)) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                System.out.println("Server says: " + reader.readLine());
                writer.println("Hello, Server!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
4. Java NIO的高级用法
4.1 文件读写操作
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class FileNIODemo {
    public static void main(String[] args) {
        String filePath = "example_nio.txt";
        Path path = Paths.get(filePath);
        String content = "Hello, Java NIO!";
        
        // Write to file using NIO
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            buffer.put(content.getBytes());
            buffer.flip();
            fileChannel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Read from file using NIO
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            fileChannel.read(buffer);
            buffer.flip();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            System.out.println(new String(bytes));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4.2 网络通信(Socket编程)
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 SocketNIODemo {
    public static void main(String[] args) {
        new Thread(SocketNIODemo::startServer).start();
        new Thread(SocketNIODemo::startClient).start();
    }

    public static void startServer() {
        try (Selector selector = Selector.open();
             ServerSocketChannel serverChannel = ServerSocketChannel.open()) {
            
            serverChannel.bind(new InetSocketAddress(8081));
            serverChannel.configureBlocking(false);
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);

            while (true) {
                selector.select();
                Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
                while (keys.hasNext()) {
                    SelectionKey key = keys.next();
                    keys.remove();

                    if (key.isAcceptable()) {
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_READ);
                        ByteBuffer buffer = ByteBuffer.wrap("Hello, Client!".getBytes());
                        client.write(buffer);
                    } else if (key.isReadable()) {
                        SocketChannel client = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(256);
                        client.read(buffer);
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        buffer.get(bytes);
                        System.out.println("Client says: " + new String(bytes));
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void startClient() {
        try (SocketChannel clientChannel = SocketChannel.open(new InetSocketAddress("localhost", 8081))) {
            clientChannel.configureBlocking(false);
            ByteBuffer buffer = ByteBuffer.allocate(256);

            while (clientChannel.read(buffer) <= 0) {
                // Wait for server response
            }
            buffer.flip();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            System.out.println("Server says: " + new String(bytes));

            buffer.clear();
            buffer.put("Hello, Server!".getBytes());
            buffer.flip();
            while (buffer.hasRemaining()) {
                clientChannel.write(buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
5. 结论

Java IO和NIO各有优缺点,在具体应用中应根据需求选择合适的API。传统的IO适合简单、低并发的场景,而NIO在高并发、大数据处理的场景中表现更佳。希望本文通过详细的对比和代码示例,能帮助读者更好地理解Java IO与NIO的区别与应用。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

๑҉ 晴天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值