NIO:通道Channel讲解

2023-11-09

      了解了缓冲区后,下来需要了解真正传输数据的通道Channel,Channel是做什么用的?再来简单回顾一下,通道顾名思义就是传递的介质,Channel就类似于传统IO中的流,是直接对接操作系统的,当我们处理好缓冲区后,就可以通过缓冲区对通道进行数据的输入输出,完成整个NIO的过程。
      Java为Channel接口提供了DatagtamChannel、FileChannel、Pipe.SinkChannel、ServerSocketChannel、SocketChannel等实现类,这些通道是根据功能来划分的,例如Pipe.SinkChannel和Pipe.SourceChannel是用于支持线程之间通信的管道,ServerSocketChannel,SocketChannel是用于支持TCP网络通信的,而DatagramChannel则是用于支持UDP网络通信的通道。

NIO使用通道进行数据读写有两种方式:
1.通过内存映射
2.通过传统IO模式,通过多次读写
通过内存映射是将数据映射到内存空间中,这样的方式明显效率是很高的,如果Channel对应的文件过大,使用映射一次将所有的文件内容映射到内存中会引起性能的下降,就可以使用第二种方式,使用传统的IO方式分多次进行

比较几种读写方式,效率从高到低是:
NIO内存映射 > NIO多次读写 > 传统IO使用缓存 > 使用普通IO

下面的两个例子都用FileChannel来说明

内存映射

Channel提供了map()方法来完成内存映射的过程,该过程会返回一个MappedByteBuffer,这个类是ByteBuffer的子类,也是一个缓存。
在这里插入图片描述
我们可以直接通过操作缓存来进行通道数据的交换

public class ChannelTest {
    public static void main(String[] args) {
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
        	//获得通道
            inChannel = new FileInputStream("e:\\txt\\beauty.jpeg").getChannel();
            //为什么不是OutputStream???
            outChannel = new RandomAccessFile("e:\\beauty.jpeg","rw").getChannel();
            long size = inChannel.size();
            //映射为缓存
            MappedByteBuffer inBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
            MappedByteBuffer outBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);
            for (int i = 0; i < size; i++) {
                outBuffer.put(inBuffer.get(i));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        		//关闭通道
                try {
                    if(inChannel!=null) {
                        inChannel.close();
                    }
                    if(outChannel!=null) {
                        outChannel.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

这个demo实现一个图片的复制,这块用到的通道是FileChannel。
观察demo,会有一个为什么读入文件通道是FileInputStream,但是写入为什么用的是RandomAccessFile?
这是因为FileChannel和SocketChannel不同,他是一个单向的通道,虽然有write方法,但是如果调用write就会抛出一个NonWritableChannelException 异常,这是因为他们都实现了ByteChannel,ByteChannel同时有read和write方法。如果用FileOutputStream映射的模式确没有WRITE_NOLY,所以只能用RandomAccessFile这种可以读,也可以写的流来获得通道,这样只用其中写的功能就可以完成了。

多次读写

public class ChannelTest2 {
    public static void main(String[] args) {
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            inChannel = new FileInputStream("e:\\beauty.jpeg").getChannel();
            outChannel = new FileOutputStream("e:\\beauty2.jpeg").getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while((inChannel.read(buffer))!=-1) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(inChannel!=null) {
                    inChannel.close();
                }
                if(outChannel!=null) {
                    outChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这种多次读写的方式和普通IO流非常相似,以前是一个缓冲数组,现在是一个缓冲区,都是分多次读入,然后再写到指定流中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NIO:通道Channel讲解 的相关文章

随机推荐

  • pytorch的语义分割------数据增广

    官方文档 https pytorch org docs stable torchvision transforms html highlight torchvision 20transforms 20functional module to
  • maven编译项目抛出out of memory

    是java堆内存过小的原因造成的 新增环境变量 MAVEN OPTS Xmx512m 问题解决
  • 【融职培训】Web前端学习 第11章 微信开发5 微信支付

    一 概述 如果需要实现微信支付功能 需要有一个已认证的微信服务号 并且开通微信支付 开通后微信会提供一个商户ID 有了这个ID才能成功调用微信支付接口 开通微信支付后 需要在微信支付后台 产品中心 gt 开发配置 中配置 JSAPI支付授权
  • 不小心在服务器上删了文件怎么恢复出厂设置,文件删除了怎么恢复?这样才能彻底清除彻底清除...

    现在人换手机就像换衣服 虽然不是一天一换 但大多数人一年一换已经成为常态 所以闲置的旧手机也越来越多 一般旧手机大家都是闲置 或者二手转卖 或是送给别人使用 如此一来 旧手机上各种数据就需要彻底清除 否则旧手机上个人信息一旦泄露 很可能会给
  • HTML教程

    第一章 HTML标签 网页格式 html 网页的开始与结束 body 网页的主体部分 显示在网页中用户可以浏览到的内容 head 网页的头部 大部分不显示在用户浏览界面 meta 网页的摘要信息 不会显示在浏览器浏览界面 title 网页标
  • 人工智能-Tansformer-全套讲解15-20章

    第21章 基于Bayesian Theory的MRC文本理解基础经典模型算法详解 1 Bayesian prior在模型训练时候对Weight控制 训练速度影响等功能详解 2 Bayesian prior能够提供模型训练速度和质量的数学原理
  • angular指令心得(ng-model)

    angular指令心得 ng model 在项目中编写指令 常常会依赖其他的指令来实现想要达到的功能 其中最常用到的便是ng model 它为我们明确了需要绑定的属性 虽然在指令中可以通过通过使用独立作用域的 来进行双向绑定 但使用ng m
  • 华清远见学习笔记—Level1—Day1—必备Linux命令和C语言基础

    本专栏为个人在华清远见嵌入式linux学习期间的笔记 希望能与各位读者共同进步 文章目录 前言 一 环境安装 1 Linux文件系统是树形结构 弱分区 重文件 2 常用EXT4分区格式 3 基础分区 二 文件和目录相关命令 1 嵌入式开发基
  • Linux进程地址空间——上篇

    目录 一 前言 二 进程地址空间 1 通过一个例子去初步的了解进程地址空间 使用VS写了一段代码 在Linux中使用vim编辑器写类似的代码 结果解析 2 什么是进程地址空间 举个例子大家就明白了画饼的意义 如何画大饼 3 详谈进程地址空间
  • nested exception is java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0

    运行springcloud项目出现如下报错 FactoryBean threw exception on object creation nested exception is java lang IllegalStateException
  • spring boot logback debug日志不输出问题

    logback配置如下
  • Redis集群一致Waiting for the cluster to join

    这是由于集群不仅要求开放连接端口 6379 还要开放集群总线端口 16379 在连接端口 10000
  • 威胁情报平台(多个平台查询)

    国内平台 微步威胁平台 微步在线X情报社区 威胁情报查询 威胁分析平台 开放社区 奇安信威胁情报中心 奇安信威胁情报中心 360威胁情报中心 https ti 360 cn 绿盟 威胁情报中心 https nti nsfocus com 新
  • 毕业设计-基于深度学习的轮胎缺陷无损检测

    目录 前言 课题背景和意义 实现技术思路 一 基于深度学习的目标检测技术及研究 二 基于主成分残差逆变换的轮胎 X 射线图像缺陷检测方法 三 基于独立成分分析的轮胎缺陷特征提取及分类方法的研究 四 深度卷积神经网络技术 实现效果图样例 最后
  • 数据库文档管理化开源项目工具SmartSQL

    数据库文档管理化开源项目工具SmartSQL 为何写该博文 由于这段时间需要理清软件的相关表结构 以及在客户端操作时使用 SQL Server Profiler 来检索一些简单的CURD sql语句 为了更好高效的理清内部的一些表结构 视图
  • react eslint解决方案整理

    eslint 解决方案整理 最近在处理react项目中报的warning 进行了以下整理 参考文档 http eslint cn docs rules 项目中遇到warning的解决 xxx is defined but never use
  • 使用EKF融合odometry及imu数据

    整理资料发现早前学习robot pose ekf的笔记 大抵是一些原理基础的东西加一些自己的理解 可能有不太正确的地方 当时做工程遇到的情况为机器人在一些如光滑的地面上打滑的情形 期望使用EKF利用imu对odom数据进行校正 就结果来看
  • python 点云配准_TEASER++:快速鲁棒的C++点云配准库

    TEASER fast certifiable 3D registration TEASER is a fast and certifiably robust point cloud registration library written
  • 在腾讯开发 QQ IM 的工作体验是怎样的?

    转载 http blog csdn net kobejayandy article details 8685271 目录 一 引言 二 个人网站 三 Oracle 支付宝 旺旺 四 淘宝技术发展 Java时代 脱胎换骨 五 淘宝技术发展 J
  • NIO:通道Channel讲解

    了解了缓冲区后 下来需要了解真正传输数据的通道Channel Channel是做什么用的 再来简单回顾一下 通道顾名思义就是传递的介质 Channel就类似于传统IO中的流 是直接对接操作系统的 当我们处理好缓冲区后 就可以通过缓冲区对通道