NIO 三大核心-Channel

23 篇文章 2 订阅
9 篇文章 0 订阅
本文介绍了JavaNIO中的通道(Channel)与流的区别,通道可以同时进行读写,支持异步操作,并能从缓冲区读写数据。FileChannel用于文件操作,SocketChannel和ServerSocketChannel则涉及网络通信。示例代码展示了如何使用FileChannel进行文件读写和复制,以及ServerSocketChannel和SocketChannel在服务器端和客户端的角色。
摘要由CSDN通过智能技术生成

通道(Channel)与流的区别:

  1. 通道可以同时进行读写,而流只能读或写
  2. 通道可以实现异步读写数据
  3. 通道可以从缓冲读数据,也可以写数据到缓冲

Channel 是NIO的一个接口,常用的Channel类有:FileChannel、DatagramChannel、ServerSocketChannel( 类似 ServerSocket ) 和 SocketChannel (类似 Socket 当客户端连接 Server的时候,会由 ServerSocketChannel 产生一个对应客户端的 SocketChannel)

FileChannel: 主要用来对本地文件进行IO操作

方法名作用
public abstract int read(ByteBuffer dst)从通道读取数据并放入缓冲区中
public abstract int write(ByteBuffer src)把缓冲区的数据写到通道中
public abstract long transferFrom(ReadableByteChannel src, long position, long count)从目标通道中复制数据到当前通道
public abstract long transferTo(long position, long count, WritableByteChannel target)把数据从当前通道复制给目标通道

写文件 示例代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

public class NIOFileChannel {
    public static void main(String[] args) throws IOException {
        String str = "Hi, NIO";
        // 创建一个输出流->channel
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\file.txt");

        // 通过fileOutStream 获得对应的FileChannel(FileChannelImpl)
        FileChannel fileChannel = fileOutputStream.getChannel();

        // 创建一个缓冲区 byteBuffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byteBuffer.put(str.getBytes(StandardCharsets.UTF_8));

        // 对buffer进行翻转
        byteBuffer.flip();

        // 将bytebuffer 数据写入到fileChannel
        fileChannel.write(byteBuffer);
        fileOutputStream.close();
    }
}

读文件 示例代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @author doubily
 * 文件读取
 */
public class NIOReadFileChannel {
    public static void main(String[] args) throws IOException {
        // 创建文件的输入流
        File file = new File("d:\\file.txt");
        FileInputStream fileInputStream = new FileInputStream(file);

        // 通过FileInputStream 获取对应的FileChannel -> 实际类型 FileChannelImpl
        FileChannel fileChannel = fileInputStream.getChannel();

        // 创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate((int)file.length());

        // 将 通道数据读入到Buffer
        fileChannel.read(byteBuffer);

        // 将byteBuffer 的字节数据 转成String
        System.out.println(new String(byteBuffer.array()));
        fileInputStream.close();
    }
}

复制文件 示例代码:

/**
 * @author doubily
 * 文件拷贝
 */
public class NIODuplicateFileChannel {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:/file.txt");
        FileChannel fileChannelRead = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("D:/file01.txt");
        FileChannel fileChannelWrite = fileOutputStream.getChannel();

//        ByteBuffer byteBuffer = ByteBuffer.allocate(512);
//        while (true) {
//            // 复位 清空buf 避免position和limit相等,循环返回0
//            byteBuffer.clear();
//            int read = fileChannelRead.read(byteBuffer);
//            // 读完
//            if (read == -1) {
//                break;
//            }
//            // 将buffer 中的数据写入到fileChannelWrite
//            byteBuffer.flip();
//            fileChannelWrite.write(byteBuffer);
//        }

        // 使用transferForm 完成拷贝
        fileChannelWrite.transferFrom(fileChannelRead, 0, fileChannelRead.size());
        // 关闭相关的流
        fileChannelRead.close();
        fileChannelWrite.close();
        fileChannelRead.close();
        fileChannelWrite.close();
    }
}

ServerSocketChannel : 在服务器端监听新的客户端 Socket 连接

方法说明
public static ServerSocketChannel open()得到一个 ServerSocketChannel通道
public final ServerSocketChannel bind(SocketAddress local)设置服务器端端口号
public final SelectableChannel configureBlocking(boolean block)设置阻塞或非阻塞模式,取值 false表示采用非阻塞模式
public SocketChannel accept()接受一个连接,返回代表这个连接的通道对家
public finalSelectionKeyregister(Selectorsel, int ops)注册一个选择器并设置监听事件

SocketChannel: 网络 IO 通道, 具体负责进行读写操作。 NIO把缓冲区的数据写入通道,或者把通道里的数据读到缓冲区

方法说明
public static SocketChannel open()得到一个 SocketChannel通道
publicfinalSelectableChannel configureBlocking(boolean block)设置阻塞或非阻塞模式,取值false表示采用非阻塞模式
public boolean connect(SocketAddress remote)连接服务器
public boolean finishConnect()如果上面的方法连接失败,接下来就要通过该方法完成连接操作
public int write(ByteBuffer src)往通道里写数据
public int read(ByteBuffer dst)从通道里读数据
public final SelectionKey register(Selector sel, int ops, Object att)注册一个选择器并设置监听事件,最后一个参数可以设置共享数据
publicfinal void close()关闭通道

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值