【Netty系列】NIO编程案例(Channel)

一、通道(Channel)使用案例

NIO 的通道类似于流,但有些区别如下:通道可以同时进行读写,而流只能读或者只能写;通道可以实现异步读写数据;通道可以从缓冲读数据,也可以写数据到缓冲。
BIO 中的 Stream 是单向的,例如 FileInputStream 对象只能进行读取数据的操作,而 NIO 中的通道(Channel)是双向的,可以读操作,也可以写操作
常用的 Channel 类有: FileChannelDatagramChannelServerSocketChannelSocketChannel 。【ServerSocketChannel 类似 ServerSocketSocketChannel 类似 Socket】。其中FileChannel 用于文件的数据读写,DatagramChannel 用于 UDP 的数据读写,ServerSocketChannelSocketChannel 用于 TCP 的数据读写。

1. FileChannel类

FileChannel 主要用来对本地文件进行 IO 操作,常见的方法有:

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

🥘案例1:本地文件写数据🥘

hello,lwz字符串写入到本地文件E:\\file01.txt中:

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

public class NIOTest1 {
    public static void main(String[] args) throws IOException {
        String str = "hello,lwz";  // 输出字符串
        // 创建一个输出流 -> channel
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\file01.txt");
        // 通过fileOutputStream获取对应的FileChannel
        FileChannel channel = fileOutputStream.getChannel();
        // 创建缓冲区,容量为1024字节
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        // 将"hello,lwz"写入到缓冲区中
        byteBuffer.put(str.getBytes());
        // 读写反转,之前是写入,现在变成读出
        byteBuffer.flip();
        // 将数据从缓冲区写入到channel
        channel.write(byteBuffer);
        // 关闭输出流
        fileOutputStream.close();
    }
}

运行结果如下:

在这里插入图片描述

🥘案例2:本地文件读数据🥘

E:\\file01.txt中的数据读入到程序中:

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

public class NIOTest2 {
    public static void main(String[] args) throws IOException {
        // 创建文件的输入流
        File file = new File("E:\\file01.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        // 获取对应通道
        FileChannel channel = fileInputStream.getChannel();
        // 创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
        // 将通道中的数据读入到缓冲区
        channel.read(byteBuffer);
        // 输出缓冲区中的数据
        System.out.println(new String(byteBuffer.array()));
        fileInputStream.close();
    }
}

运行结果如下:

在这里插入图片描述
🥘案例3:使用一个 Buffer 完成文件拷贝🥘

0.txt中的数据hello,lwz写入到1.txt中:

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

public class NIOTest3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("E:\\0.txt");
        FileChannel channel1 = fileInputStream.getChannel();
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\1.txt");
        FileChannel channel2 = fileOutputStream.getChannel();
        // 创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(512);
        while (true) { // 循环读取
            byteBuffer.clear(); // 清空 buffer
            int read = channel1.read(byteBuffer);
            if (read == -1) { // 表示读完
                break;
            }
            System.out.println("读了" + read + "字节的数据");
            // 将buffer中的数据写入到 channel2--1.txt
            byteBuffer.flip();
            channel2.write(byteBuffer);
        }
        // 关闭相关的流
        fileInputStream.close();
        fileOutputStream.close();
    }
}

运行结果如下:

在这里插入图片描述
在这里插入图片描述

🥘案例4:使用一个 transferFrom 方法完成文件拷贝🥘

D:\\old.jpg拷贝到E:\\new.jpg

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class NIOTest4 {
    public static void main(String[] args) throws IOException {
        // 创建相关输入、输出流
        FileInputStream fileInputStream = new FileInputStream("D:\\old.jpg");
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\new.jpg");
        // 创建相应通道
        FileChannel sourceCh = fileInputStream.getChannel();
        FileChannel destCh = fileOutputStream.getChannel();
        // 使用transferFrom完成拷贝
        destCh.transferFrom(sourceCh, 0, sourceCh.size());
        // 关闭相关通道和流
        sourceCh.close();
        destCh.close();
        fileInputStream.close();
        fileOutputStream.close();
    }
}

运行结果如下,可以发现在E:\\new.jpg中出现该图片:

在这里插入图片描述


  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值