使用NIO把文件转二进制数组

NIO(Non-blocking I/O)是Java中提供的一种I/O操作方式,与传统的I/O方式相比,具有更高的效率和可扩展性。下面来详细介绍NIO的底层实现机制和相关概念。

  1. Channel

Channel是NIO中的一个基础概念,表示数据源与目标的连接通道。在NIO中,所有的I/O操作都是通过Channel进行的。Channel类似于传统I/O中的文件描述符,但它可以同时支持读写操作,并且可以使用非阻塞模式进行操作。常见的Channel类型包括FileChannel、SocketChannel和ServerSocketChannel等。

  1. Buffer

Buffer是NIO中的另一个重要概念,用于存储数据。Buffer是一个数组对象,可以容纳多个元素,其中每个元素可以是基本数据类型或其他对象类型。Buffer类似于传统I/O中的缓冲区,但它可以根据需要自动增长或收缩,并支持直接内存访问,因此具有更高的效率和灵活性。常见的Buffer类型包括ByteBuffer、ShortBuffer和CharBuffer等。

  1. Selector

Selector是NIO中的第三个重要概念,用于多路复用和事件驱动式I/O。在NIO中,可以使用Selector来同时监视多个Channel对象的状态,并在有I/O事件发生时进行响应处理。Selector可以将一个线程绑定到多个Channel上,从而允许在单个线程中同时处理多个I/O请求。

  1. Channel和Buffer的操作

NIO中的读写操作是通过Channel和Buffer对象进行的。为了进行读取或写入,需要先将数据放入Buffer缓冲区中,然后再通过Channel将其传输到目标位置。当数据被写入Channel时,Buffer会自动切换为读模式;而当数据从Channel中读取时,Buffer会自动切换为写模式。可以使用Buffer类的flip()方法来切换Buffer的模式。

  1. 非阻塞模式和选择器

NIO提供了非阻塞模式和选择器机制,用于实现高效率、高可扩展性的网络编程。在非阻塞模式下,I/O操作不会阻塞线程,而是立即返回,并由应用程序负责处理I/O事件。这样可以避免线程阻塞并提高系统的并发处理能力。在选择器机制下,可以将一个线程同时绑定到多个Channel上,并使用Selector监视这些Channel的状态。当Channel发生I/O事件时,Selector会通知应用程序进行处理。

    public static byte[] toByteArrayNIO(String filename) throws IOException {
        //1.获取文件路径,检查是否存在
        File file = new File(filename);
        if (!file.exists()) {
            throw new FileNotFoundException(filename);
        }
        //2.创建FileInputStream对象和FileChannel对象,并使用FileChannel对象将输入流数据读取到ByteBuffer缓冲区中。
        FileChannel channel = null;
        FileInputStream fs = null;
        try {
            fs = new FileInputStream(file);
            channel = fs.getChannel();
            //3.1 创建一个指定大小的buffer对象
            ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
            //3.2 从channel对象中读取数据并放入缓冲区(只要字节>0,while这里一直读取)
            while (channel.read(byteBuffer) > 0) {
                // System.out.println("reading");
            }
            //3.3 将ByteBuffer缓冲区内容复制到一个byte数组中,并返回该数组
            return byteBuffer.array();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            //4.在finally块中关闭FileChannel对象和FileInputStream对象
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值