NIO Buffer与Channel实现文件IO

在这里插入图片描述

  • NIO提供的Channel表示与file或socket唯一关联,可以理解成程序通过Buffer将数据写入channel就表示将数据写入了file或socket,从channel中将数据读入Buffer就表示从file或socket中读取了数据到程序中。
  • BIO是同步阻塞的,NIO是同步非阻塞的,通过将与socket唯一关联的channel注册到Selector,通过select()轮询,实现同步非阻塞。而AIO才是真正异步非阻塞的,异步表示实际的IO操作是由操作系统完成的,而不是程序完成的,操作系统完成IO后将结果返回给程序。只要是程序完成的IO操作,都是同步的。

另一篇博文NIO同步非阻塞Selector轮询实现网络socket,通过详细的注释,介绍并实现了NIO同步非阻塞的socket
详细分析见代码注释

  • 向文件中写数据
package niodemo;

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


public class NIOWriteDataToFile {
    public static void main(String[] args) throws IOException {
        String str  = "hi,my name is fine-adj!";

        //对程序来说往文件里写是输出流
        FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\aaa.txt");

        //创建buffer
        //由于file和socket存数据都是二进制的字节,所以常用的是ByteBuffer,
        //创建容量capacity大小是1024个字节的buffer
        int bufferSize = str.length();
       ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize); 

       //创建channel : 获取输出流对应的channel
        FileChannel fileChannel = fileOutputStream.getChannel();

        //将数据写入buffer
        byteBuffer.put(str.getBytes());

        //!!!!!!!!!!!向buffer写入数据后buffer要调用flip,将其置为可读状态:buffer是双向的
        byteBuffer.flip();

        //将buffer中数据写入channel
        fileChannel.write(byteBuffer);   //由于channel是与文件关联的【与socket的client关联的】,所以写入channel就相当于写入文件

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

    }
}
  • 从文件中读数据
package niodemo;

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

public class NIOReadFromFile {
    public static void main(String[] args) throws IOException {
        //从文件里读取数据

        File file = new File("C:\\Users\\Administrator\\Desktop\\aaa.txt");
        //对于程序来说输入流,创建文件输入流
        FileInputStream fileInputStream = new FileInputStream(file);

        //获取输入流对应的channel,channel是与file/socket/client唯一对应的
        FileChannel fileChannel  = fileInputStream.getChannel(); //!!!【file已经与channel关联了】!!!

        //创建buffer,由于file/socket的数据是二进制存储的。注意创建大小的时候是这样的:(int)file.length()
        ByteBuffer byteBuffer = ByteBuffer.allocate((int)file.length());
        
        //把channel中的数据读入buffer
        fileChannel.read(byteBuffer);

        //byteBuffer中装入数据后,置为可读状态
        byteBuffer.flip();

        //程序从buffer中读数据
        System.out.println(new String(byteBuffer.array()));

        //关闭流
        fileChannel.close();
        fileInputStream.close();

    }
}
  • 文件拷贝
package niodemo;

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

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

        //对于程序来说是把数据从文件1取出来,即数据从文件1流入程序
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Administrator\\Desktop\\aaa.txt");

        //对于程序来说是把数据写入文件2,即数据从程序流入文件2
        FileOutputStream outputStream = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\bbb.txt");

        //创建文件aaa的channel
        FileChannel fileChannel1 = fileInputStream.getChannel();
        //创建文件2的channel
        FileChannel fileChannel2 = outputStream.getChannel();

        //创建buffer: 共用一个buffer,因为buffer是双向的
        ByteBuffer byteBuffer = ByteBuffer.allocate(512);

        //从文件1中循环取数据,写入buffer,
        while (true){
            //!每次向buffer写数据之前,将buffer的position属性置为0,调用clear,表示可写状态(双向的)
            byteBuffer.clear();  //将position的位置置为0,表示让数据从buffer的0开始写入!!!!!!!!!!!
            //将文件1中的数据写入缓冲区buffer,即将文件1对应的channel中的数据写入buffer
            int read = fileChannel1.read(byteBuffer);
            if(read == -1){    //循环读数据的时候,用while就一定要用break, channel的read返回-1表示channel中数据读完了。
                break;
            }
            //buffer写入数据后置为可读状态
            byteBuffer.flip();                     //!!!!!!!!!!将buffer置为可读状态。(双向的)

            //从buffer中将数据写入channel,即拷贝到文件2
            fileChannel2.write(byteBuffer);
        }

        //关闭流
        fileChannel1.close();
        fileChannel2.close();
        fileInputStream.close();

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值