网络I/o编程模型4 NIo之chanel通道实现文件复制

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络I/o编程模型4 NIo之chanel通道实现文件复制相关的知识,希望对你有一定的参考价值。

一 各种代码操作案例

1.1 向本地文件写数据

1.代码

package com.ljf.netty.nio;

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

/**
 * @ClassName: WriteToLocalDemo
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/14 16:03:05
 * @Version: V1.0
 **/
public class WriteToLocalDemo 
    public static void main(String[] args) throws IOException 
        String str="hello,中国";
        String dstPath="d:/liu.txt";
        //创建一个输出流
        FileOutputStream fileOutputStream=new FileOutputStream(dstPath);
        //通过fileOutputStream获取对应的FileChannel
        FileChannel fileChannel=fileOutputStream.getChannel();
        //创建一个缓冲区 ByteBuffer
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
        //将str内容放到缓存中
        byteBuffer.put(str.getBytes());
        //对bypteBuffer进行flip
        byteBuffer.flip();
        //将byteBuffer数据写入到fileChannel中
        fileChannel.write(byteBuffer);
        fileChannel.close();

    

2.效果

 1.2  读取本地文件进行输出

1.代码

package com.ljf.netty.nio;

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

/**
 * @ClassName: ReadFromLocalDemo
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/14 16:15:14
 * @Version: V1.0
 **/
public class ReadFromLocalDemo 
    public static void main(String[] args) throws IOException 
        File file=new File("d:/liu.txt");
        //创建文件的输入流
        FileInputStream fileInputStream=new FileInputStream(file);
        //通过fileinputstream 获取对应的filechannel
        FileChannel fileChannel=fileInputStream.getChannel();
        //创建缓存区
        ByteBuffer byteBuffer=ByteBuffer.allocate((int)file.length());
        //将通道的数据读入到Buffer
        fileChannel.read(byteBuffer);
        System.out.println(new String(byteBuffer.array()));
        fileChannel.close();
    

2.结果

1.3  实现文件的复制操作

1.代码

package com.ljf.netty.nio;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @ClassName: FileChannel01
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/14 16:01:41
 * @Version: V1.0
 **/
public class FileChannel01 
    public static void main(String[] args) throws IOException 
        //读
        FileInputStream fileInputStream=new FileInputStream("d:/liu.txt");
        FileChannel fileChannel01=fileInputStream.getChannel();
        //写
        FileOutputStream fileOutputStream=new FileOutputStream("d:/liu2.txt");
        FileChannel fileChanne02=fileOutputStream.getChannel();
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
        //循环
        while(true)
            //清空buffer,防止上一次存储的数据存储,
            byteBuffer.clear();
           int read= fileChannel01.read(byteBuffer);
           if(read==-1)
            System.out.println("已经读完,退出");
            break;
           
           //将buffer中的数据写入到filechannel02中
            byteBuffer.flip();
           fileChanne02.write(byteBuffer);

        
        fileChannel01.close();
        fileChanne02.close();
        System.out.println("结束......");
    

2.结果

 1.4  使用transferFrom实现文件的复制操作

1.代码

package com.ljf.netty.nio;

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

/**
 * @ClassName: TransferFileDemo
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/14 16:55:18
 * @Version: V1.0
 **/
public class TransferFileDemo 
    public static void main(String[] args) throws IOException 
        FileInputStream   fileInputStream=new FileInputStream("d:/liu.txt");
        FileOutputStream  fileOutputStream=new FileOutputStream("d:/liu3.txt");
        //获取各个流对应的filechannel
        FileChannel sourceCh=fileInputStream.getChannel();
        FileChannel destCh=fileOutputStream.getChannel();
        //使用transferFrom完成复制
        destCh.transferFrom(sourceCh,0,sourceCh.size());
        //关闭通道
        sourceCh.close();
        destCh.close();
        fileInputStream.close();
        fileOutputStream.close();




    

2.结果

 1.5  通过使用多个buffer完成读写操作

//Scattering:将数据写入到buffer时,可以采用buffer数组,依次写入【分散】
//Gathering: 从buffer读取数据时,可以采用buffer数组,依次读

1.代码

package com.ljf.netty.nio;

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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: BacthCopy
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/14 18:09:38
 * @Version: V1.0
 **/
public class BacthCopy 
    public static void main(String[] args) throws IOException 
        //Scattering:将数据写入到buffer时,可以采用buffer数组,依次写入【分散】
        //Gathering: 从buffer读取数据时,可以采用buffer数组,依次读
        //使用 ServerSocketChannel和socketChannel网络
        ServerSocketChannel  serverSocketChannel=ServerSocketChannel.open();
        InetSocketAddress inetSocketAddress=new InetSocketAddress(7000);
        //绑定端口到socket,并启动
        serverSocketChannel.socket().bind(inetSocketAddress);
        //创建buffer数组
        ByteBuffer[] byteBuffers=new ByteBuffer[2];
        byteBuffers[0]=ByteBuffer.allocate(5);
        byteBuffers[1]=ByteBuffer.allocate(3);
        //等客户端连接
        SocketChannel socketChannel=serverSocketChannel.accept();
        int messageLenght=8;
        //循环读取
        while(true)
            int byteRead=0;
            while(byteRead<messageLenght)
                long l=socketChannel.read(byteBuffers);
                byteRead+=l;
                System.out.println("读取字节数:"+byteRead);
                Arrays.asList(byteBuffers).stream().map(bb-> "位置:"+bb.position()+" limit:"+bb.limit()).forEach(System.out::println);
                List<ByteBuffer> dataList=Arrays.asList(byteBuffers);
                /*
              List<String> hhList=  dataList.stream().map(bb-> "位置:"+bb.position()+" limit:"+bb.limit()).collect(Collectors.toList());
              for(String hh:hhList)
                  System.out.println("jieguo:"+hh);
              
              */

            
            //将所有的buffer进行flip
            Arrays.asList(byteBuffers).forEach(buffer->buffer.flip());
            //将数据读出,显示到客户端
            long byteWirte=0;
            while(byteWirte<messageLenght)
                long l=socketChannel.write(byteBuffers);
                byteWirte=+l;
            
            //将所有的buffer进行clear
            Arrays.asList(byteBuffers).forEach(buffer->buffer.clear(););
            System.out.println("byteRead:"+byteRead+" bytewrite:"+byteWirte+"messagelength:"+messageLenght);
        
    

2.测试结果

cmd窗口,输入: telnet localhost 7000

按住,ctr+] 进行发送数据:

send zhongguo nihao

 

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于网络I/o编程模型4 NIo之chanel通道实现文件复制的主要内容,如果未能解决你的问题,请参考以下文章

04-AIO通讯模型

网络I/o编程模型5 Nio之buffer的操作和常用方法

网络I/o编程模型6 Nio之Selector以及NIO客户服务通讯

网络通信之 AIO 和 BIO和 NIO

网络I/o编程模型7 Nio实现聊天室

java之BIO简介