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讲解 的相关文章

  • Files#delete(Path) 和 File#delete() 之间的区别

    我正在使用带有 java 7 update 6 的 Windows 7 并发现这种奇怪的 至少对我来说 行为 我有两个文件E delete1 txt and E delete2 txt两者都是只读文件 当我尝试删除如下文件时 它会被删除而没
  • 关闭从 TCP 连接读取的 goroutine,而不关闭连接

    我喜欢 Go 在内部处理 I O 多路复用的方式epoll还有另一种机制并自行调度绿色线程 此处为 go routine 从而可以自由地编写同步代码 我知道 TCP 套接字是non blocking and read会给EAGAIN当没有可
  • 为什么Java NIO专门引入Buffer类而不是使用数组?

    有人问我一个问题 为什么字节数组不够用 NIO专门引入了一个类Buffer 这个问题的好答案是什么 它只是一种简化读 写操作的包装类吗 如果可能的话 请给我们举个例子来说明我们如何从中受益Buffer不能 很难用数组完成的类 None
  • 每个 UDP 数据报的 Netty 不同管道

    我们有一个已经在 TCP IP 中实现的服务器 但现在我们要求该协议也支持 UDP 发送的每个 UDP 数据报都包含我需要解码的所有内容 因此这是一个非常简单的回复和响应系统 数据报中的数据由换行符分隔 服务器启动时的引导代码如下所示 SE
  • Java N/IO 中的行分隔符?

    使用以下命令写入 txt 文件时如何插入新行java nio file 以下代码生成一个只有一行的txt文件ABCDEF 而不是两条单独的线ABC and DEF public static void main String args th
  • 通道是否通过引用隐式传递

    gotour 有这个频道示例 https tour golang org concurrency 2 https tour golang org concurrency 2 package main import fmt func sum
  • 让Java文件传输更高效

    我有两台无线计算机连接到 N 个无线路由器 每台 PC 的连接速度都在 108 150Mbps 之间 理论上 在绝对最佳的条件下 我应该能够以 13 5MB s 到 18 75MB s 的速度传输 第一台计算机 正在发送 使用非常快的 SS
  • 定制频道wifi直连

    谁能告诉我 有没有自定义 wifi direct 频道的选项 我不仅需要在 ch1 ch6 和 ch11 之间进行自定义 还需要在我选择的其他频道中进行自定义 我怎样才能做到这一点 要更改设备 Wifi Direct 的频道 您需要执行以下
  • 尝试复制大文件时出现 NIO 错误

    我有将文件复制到另一个位置的代码 public static void copyFile String sourceDest String newDest throws IOException File sourceFile new Fil
  • AsynchronousByteChannel 的线程含义

    Javadoc 的AsynchronousByteChannel read http download oracle com javase 7 docs api java nio channels AsynchronousByteChann
  • 将切片的所有项目添加到通道中

    在 Go 中 是否有比以下更惯用的方法将数组 切片的所有元素添加到通道中 ch make chan string values string lol cat lolcat go func for v range values ch lt v
  • 具有 AsynchronousServerSocketChannel 的多线程服务器

    我必须实现一个应该接受更多连接的服务器 没有任何更深入的思考 我决定使用新的 JAVA NIO 2 类 我目前的做法是 final Semaphore wait new Semaphore 1 while true wait acquire
  • 如何在Python中使用socket创建通道

    我之前已经启动过Python几次 现在我正在创建一个套接字服务器 我已经让服务器与多个客户端一起使用多个线程 万岁 但我正在寻找我无法调用的功能 我什至不知道它是否存在 我想创建一种客户端通道可以发送不同类型的消息 一个例子 我创建一个通道
  • Jetty 和其他容器如何在遵守 Servlet 规范的同时利用 NIO?

    我是 NIO 的新手 我正在尝试弄清楚 Jetty 如何利用 NIO 我对使用 Blocking IO 的传统 servlet 容器如何服务请求的理解如下 请求到达 分配一个线程来处理请求和 servlet 方法 doGet等 被调用 Se
  • 通过 Django Channels 和 Websockets 将实时更新推送到客户端

    我正在尝试制作一个向客户端显示实时更新数据的页面 该网站的其余部分是使用 Django 构建的 因此我尝试使用 Channels 来实现此目的 我显示的数据保存在 JSON 文件和 MySQL 数据库中 以便在网站的其他部分进行进一步计算
  • 将密钥添加到选定的密钥集中

    我正在编写一个 NIO 服务器 并希望响应用户请求 即将一些数据写入通道 Selector selector if selector selectNow 0 if key isReadable SocketChannel channel k
  • Django Channels/Daphne 内部服务器错误“‘dict’对象不可调用”

    我在连接到我的网站时收到此错误 因为它正在运行频道 2018 03 25 20 59 19 049 ERROR http protocol Traceback most recent call last File home virtuale
  • Java 7 watchservice获取文件更改偏移量

    我刚刚尝试使用 Java 7 WatchService 来监视文件的更改 这是我敲出的一些代码 WatchService watcher FileSystems getDefault newWatchService Path path Pa
  • 当涉及多个渠道时,select 如何工作?

    我发现在多个非缓冲通道上使用 select 时 例如 select case lt chana case lt chanb 即使两个通道都有数据 但在处理此选择时 case chana 和 case chanb 的跟注不平衡 package
  • 将 LongBuffer/IntBuffer/ShortBuffer 转换为 ByteBuffer

    我知道一种将 byte short int long 数组转换为 ByteBuffer 的快速方法 然后获取字节数组 例如 要将字节数组转换为短数组 我可以这样做 byte bArray 1 0 0 0 0 0 0 0 1 0 0 0 0

随机推荐

  • 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中的流 是直接对接操作系统的 当我们处理好缓冲区后 就可以通过缓冲区对通道