Java NIO Channel 演示

Java NIO Channel 演示,第1张

Java NIO Channel 演示

Java NIO Channel 模型演示

一、读写概念

1.Channel 读写概念 二、FileChannel 文件读写方法

1.写文件2.读文件3.复制文件4.修改文件 三、ServerSocketChannel Buffer 聚集和分散

1.启动一个ServerSocketChannel2.通过Telnet连接:telnet 127.0.0.1 7800 按【CTRL+]】组合键进入发送数据状态

一、读写概念 1.Channel 读写概念
在UTF-8编码中:
一个中文字符等于三个字节,一个中文标点符号占三个字节
一个英文字符等于一个字节,一个英文标点占一个字节
一个数字符号等于一个字节
read  ---> 从通道读取数据写入 Buffer
write ---> 将 Buffer 数据写入通道
二、FileChannel 文件读写方法 1.写文件
public static void saveFile() throws IOException {
    String str = "Hello Moon";
    String filePath = "save.txt";
    //创建一个输出流->channel
    FileOutputStream fileOutputStream = new FileOutputStream(filePath);
    //通过FileOutputStream获取 对应的 FileChannel
    //这个FileChannel 真实类型是 FileChannelImpl
    FileChannel fileChannel = fileOutputStream.getChannel();
    //创建一个缓冲区Buffer
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    //将Str 放入 Buffer
    buffer.put(str.getBytes(StandardCharsets.UTF_8));
    //对ByteBuffer 进行反转 flip
    buffer.flip();
    //将buffer数据写入通道fileChannel
    fileChannel.write(buffer);

    //关闭流
    fileOutputStream.close();
}

2.读文件
public static void readFile() throws IOException {
    //创建文件输入流
    File file = new File("save.txt");
    FileInputStream fileInputStream = new FileInputStream(file);
    //获取FileChannel
    FileChannel fileChannel = fileInputStream.getChannel();
    //创建字节缓冲区
    ByteBuffer buffer = ByteBuffer.allocate((int)file.length());
    //将通道内数据读到缓冲区
    fileChannel.read(buffer);
    //将buffer转换为string
    System.out.println(new String(buffer.array()));
    fileInputStream.close();
}

3.复制文件
public static void copyFile() throws IOException {

    //1.创建一个输出流->channel
    FileInputStream fileInputStream = new FileInputStream("save.txt");
    //2.获取输入流通道
    FileChannel readChannel = fileInputStream.getChannel();
    //3.创建输出流
    FileOutputStream fileOutputStream = new FileOutputStream("copy.txt");
    //4.获取输出流通道
    FileChannel writeChannel = fileOutputStream.getChannel();
    //5.定义 512 字节的缓冲区
    ByteBuffer buffer = ByteBuffer.allocate(512);
    while (-1 != readChannel.read(buffer)){
        //切换读写状态并输出
        buffer.flip();
        writeChannel.write(buffer);
        //重置buffer 否则position与limit一致时 缓冲区填满无法在增加新数据
        buffer.clear();
    }
    
    fileInputStream.close();
    fileOutputStream.close();
}
4.修改文件
public static void modifyFile() throws IOException {

    RandomAccessFile randomAccessFile = new RandomAccessFile("save.txt","rw");
    //获取通道
    FileChannel fileChannel = randomAccessFile.getChannel();
    //定义编辑区域
    
    MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,5);

    mappedByteBuffer.put(0,(byte)'h');

    fileChannel.close();

}
三、ServerSocketChannel Buffer 聚集和分散 1.启动一个ServerSocketChannel
package com.example.netty.channel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;


public class NIOServerSocketChannel {

    

    public static void main(String[] args) throws IOException {

        //使用 ServerSocketChannel 和 SocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress inetSocketAddress = new InetSocketAddress(7800);
        serverSocketChannel.socket().bind(inetSocketAddress);
        //创建Buffer数组
        ByteBuffer[] byteBuffers = new ByteBuffer[2];
        byteBuffers[0] = ByteBuffer.allocate(5);
        byteBuffers[1] = ByteBuffer.allocate(3);
        //等待客户端连接(TELNET)
        SocketChannel socketChannel = serverSocketChannel.accept();
        //假定从客户端读取 8 字节
        int messageLength = 8;
        //循环读取
        while (true){

            long byteRead = 0;

            while (byteRead < messageLength){
                long read = socketChannel.read(byteBuffers);
                byteRead += read;
                //打印buffer标志
                Arrays.stream(byteBuffers).forEach(buffer->{
                    System.out.println("position:" + buffer.position() + "   limit:" + buffer.limit());
                });
            }

            //读写切换
            Arrays.stream(byteBuffers).forEach(buffer->{
                buffer.flip();
            });

            //将数据读出显示到客户端
            long byteWrite = 0;
            while (byteWrite < messageLength){
                long write = socketChannel.write(byteBuffers);
                byteWrite += write;
            }

            //清空
            Arrays.stream(byteBuffers).forEach(buffer->{
                buffer.clear();
            });

            //打印读写情况
            System.out.println("byteRead:" + byteRead + "   byteWrite:" + byteWrite);
        }
    }
}

2.通过Telnet连接:telnet 127.0.0.1 7800 按【CTRL+]】组合键进入发送数据状态

第一次发送 6 个字节发现,缓冲区数组未写满,相当于阻塞在此处
继续发送两个字节过来

第二次直接发送 8 个字节发现,程序正常下行

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5712638.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存