搞活系列-Java NIO之偏偏不用buffer.flip()会出现什么问题?

最近看博客又看到了Java NIO相关的博客,其中有讲解NIO和传统IO关于文件复制的文章,看到了如下的代码:

	/***
     * channel用例
     * 基于channel的文件复制
     */
    @Test
    public void fileCopyByChannel(){
        try {
            FileInputStream fileInputStream = new FileInputStream(fielPathIN);
            FileOutputStream fileOutputStream = new FileOutputStream(fielPathOUT);
            FileChannel inputStreamChannel = fileInputStream.getChannel();
            FileChannel outputStreamChannel = fileOutputStream.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int i = 1;
            while ((i = inputStreamChannel.read(buffer) )!= -1) {
                buffer.flip();
                Charset charset = StandardCharsets.UTF_8;
                outputStreamChannel.write(buffer);
                buffer.clear();
            }
            fileInputStream.close();
            fileOutputStream.close();
            inputStreamChannel.close();
            outputStreamChannel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

逻辑也比较简单,只是将一个文件中的文本内复制到另外一个文件中。

关键知识点

  • FileInputStream 、FileOutputStream 通过.getChannel()获取FileChannel
  • ByteBuffer.allocate(1024)分配堆内存,还有另外一种分配直接内存的方式allocateDirect。两者分配的内存前面的是归JVM管理的,儿后者不归JVM管理
  • buffer.flip()切换为读模式
  • buffer.flip()清空buffer。注意:并不是清空数据,而是重置状态

开始搞活

刚刚看到这段代码,我迫不及待去试了下,很nice!然后,脑子里就出了一个很奇怪的想法:如果在while循环里面没有buffer.flip()会怎样。

while中如果没有buffer.flip()

说搞就搞,注解注释掉,截图为证
在这里插入图片描述
运行一下代码看看效果,结果真的运行完成了,出乎意料了,难道flip可有可无了?然后就去磁盘里面看了代码运行完成的文件
在这里插入图片描述
看到这里,果然有问题,那就是flip方法是必须要有的。那么,为什么生成的代码只有源文件的一部分呢?是哪一部分呢?

flip方法详细解释

flip()方法将缓冲区的limit设置为当前的position,同时将position设置为0,以准备读取缓冲区中的数据。

clear方法详细解释

  • 将position重置为0,以便下一次写入新的数据。
  • 将缓冲区的limit设置为缓冲区的容量,表示缓冲区的可写入或可读取的上限。

显然,每次循环的最后都调用了clear方法,都会将buffer重置,所以每次都能从channel中读取到数据;因为没有调用flip方法,所以除了最后一次循环,之前循环读取完数据之后,postion、limit和capcity都在buffer的最后了,而读取的时候读的内容是从postion开始,一直到limit结束。
因为你最后一次读取如果不是1024的整数倍,假如说是100,那这一次的循环buffer的position是101,limit是1024,capcity是1024,那么将读取上一次从101-1024之间的内容。而除了最后一次循环的之前所有循环都读取不到数据。

说着可能太抽象了,还是画个图说明一下
在这里插入图片描述
所以说,最后一次读取到的是上一次没有覆盖完的内容。

那如果循环里面没有clear方法会怎么样呢?

while中如果没有buffer.clear()

详细看看以上关于clear方法的介绍,应该能知道会出现什么结果。因为clear会重置buffer的状态,如果不重置,那么从channel读取数据写入到buffer中时,只有第一次会是成功写入的,第一次之后position、limit和capcity都将指向最后,而写入时,要从position开始写一直到capcity结束;第一次写入完成之后将一直读取不了channel中的数据,因此也将会程序也将死循环。

总结

  • buffer如果是写入之后要读取,那么读取之前一定要先flip
  • buffer如果是读取之后要写入,那么写入之前一定要先clear

以上就是本篇文章所有内容,如果有写的不对的地方,欢迎大家指正,谢谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/53126.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

黑苹果如何在macOS Sonoma中驱动博通网卡

准备资源(百度:黑果魏叔 下载) 资源包中包含:AirportBrcmFixup.kext/IOSkywalkFamily.kext/IO80211FamilyLegacy.kext/OpenCore-Patcher 使用方法: 1.将 csr-active-config 设置为 03080000 全选代码 复制 2.在 …

如何进行软件回归测试

什么是软件回归测试,如何进行回归测试,进行回归测试时有哪些常用的方法? 回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误的一种测试方法。回归测试是指重复以前的全部或部分的相同功能…

2,认识N(logN)的排序【p3】

认识N( logN} 的排序 2.1归并排序2.1.1代码实现归并排序2.1.1.1自己c实现归并排序2.1.1.2gptc实现归并排序2.1.1.3总结2.1.1.4比较行为 2.1.2归并排序使用master公式2.1.3归并排序的扩展2.1.3.1小和问题2.1.3.2逆序对问题 2.2快排、荷兰国旗问题2.2.1问题一2.2.2问题二(荷兰国旗…

数电基础知识学习笔记

文章目录: 一:逻辑门 1.逻辑门电路的分类 1.1 按逻辑(逻辑门) 1.1.1 逻辑定义 1.1.2 常见数字电路相关符号 1.1.3 电路图表示 1.1.4 逻辑门电路图像符号 1.2 按电路结构 1.3 按功能特点 2.高低电平的含义 3.常见的门…

C#实现数据库数据变化监测(sqlservermysql)

监测数据库表数据变化,可实现数据库同步(一主一从(双机备份),一主多从(总部数据库,工厂1,工厂2,工厂数据合并到总部数据)) sqlserver 启用数据库…

uni-app在小米手机上运行【步骤细节】

注意细节重点: 1.手机使用数据线与电脑连接,手机连接模式必须是传输文件模式 2.手机必须打开开发者模式 3.打开开发者模式后,仔细浏览并调整USB调试权限,重点打开USB是否允许安装按钮!!! 操作步…

黄东旭:The Future of Database,掀开 TiDB Serverless 的引擎盖

在 PingCAP 用户峰会 2023 上, PingCAP 联合创始人兼 CTO 黄东旭 分享了“The Future of Database”为主题的演讲, 介绍了 TiDB Serverless 作为未来一代数据库的核心设计理念。黄东旭 通过分享个人经历和示例,强调了数据库的服务化而非服务化…

020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试 上节学习了FatFs文件系统的相关知识,这节内容继续学习在STM32上如何移植FatFs文件系统,并且实现文件的创建、读、写与删除等功能。各位看官觉得还行的话点点赞&#xff0c…

Spring Tool Suite 4

参考:Spring tool suite4 安装及配置_springtoolsuite4_猿界零零七的博客-CSDN博客 下载:Spring | Tools 将下载的JAR进行解压两次,直至解压出contents中的sts 双击启动 第一次打开需要指定工作区文件夹 配置Maven的config 安装插件

(笔记)Layout知识点汇总(积累量变)

Layout知识点汇总 布线1、电容电阻中间不要穿线2、线宽不要超过焊盘,引出后加粗 拐角1、layout:钝角走线 线宽间距1、注意和差分信号线的距离 焊盘1、焊盘中心出线2、线连接到焊盘中心 布局1、时钟线包地处理2、音频的左右声道,加粗&#xff…

【多模态】18、ViLD | 通过对视觉和语言知识蒸馏来实现开集目标检测(ICLR2022)

文章目录 一、背景二、方法2.1 对新类别的定位 Localization2.2 使用 cropped regions 进行开放词汇检测2.3 ViLD 三、效果 论文:Open-vocabulary Object Detection via Vision and Language Knowledge Distillation 代码:https://github.com/tensorflo…

C语言每日一题之整数求二进制1的个数

今天分享一道题目&#xff0c;用三种方法来求解 二进制1的个数 方法1 我们的十进制除10和取余数就可以得到我们每一位的数字&#xff0c;那我们的二进制也可 以 #include<stdio.h> int num_find_1(unsigned int n) {int count 0;while (n){if (1 n % 2){count;}n / 2…

element中tabs组件,click事件点击拿到当前item的所有数据

话不多说&#xff0c;直接上代码&#xff1a; 添加一个:value&#xff0c;然后在用JSON.stringify(item)转一下就可以了&#xff0c;这样就会存在$attrs.value这个里面了。 接着在点击事件里面获取使用el.$attrs.value&#xff0c;注意这里在拿到这个值时&#xff0c;再用JSON…

事务的隔离级别以及传播机制的详细讲解

1.为什么需要事务&#xff1f; 事务就是将一组操作封装成一个执行单元&#xff0c;要么全部执行成功&#xff0c;要么全部执行失败 ⽐如转账分为两个操作&#xff1a; 第⼀步操作&#xff1a;A 账户 -100 元第⼆步操作&#xff1a;B 账户 100 元 如果没有事务&#xff0c;第⼀…

SQL-每日一题【1173. 即时食物配送 I】

题目 配送表: Delivery 如果顾客期望的配送日期和下单日期相同&#xff0c;则该订单称为 「即时订单」&#xff0c;否则称为「计划订单」。 查询即时订单所占的百分比&#xff0c; 保留两位小数。 查询结果如下所示。 示例 1: 解题思路 1.题目要求我们查询出顾客期望的配送日…

回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测

回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现SO-CNN-LS…

Ubuntu20.04安装Autoware.universe并与Awsim联调

文章目录 引言一、安装依赖1.1 安装git1.2 克隆Autoware到本地1.3 自动安装相关依赖1.4 安装显卡驱动1.5 安装ROS2 Galactic1.6 安装ros2_dev_tools1.7 安装rmw_implementation1.8 安装pacmod1.9 安装autoware_core1.10 安装autoware universe dependencies1.11 安装pre_commit…

论文阅读-BotPercent: Estimating Twitter Bot Populations from Groups to Crowds

目录 摘要 引言 方法 数据集 BotPercent架构 实验结果 活跃用户中的Bot数量 Bot Population among Comment Sections Bot Participation in Content Moderation Votes Bot Population in Different Countries’ Politics 论文链接&#xff1a;https://arxiv.org/pdf/23…

解密低价正规渠道的来源:影视会员肯德基点餐直充api接口

话费充值 接口已经整合移动、联通、电信三网话费充值渠道。话费可以说是全民所需&#xff0c;对于平台引流&#xff0c;增强平台日活跃度可以提供不小的帮助。 肯德基在线点餐 接口整合了各大城市的肯德基门店&#xff0c;支持门店选择&#xff0c;在线点餐 提前点餐领取&a…

Xilinx AXI VIP使用教程

AXI接口虽然经常使用&#xff0c;很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP&#xff0c;可以当做AXI的master、pass through和slave&#xff0c;本次内容我们看下AXI VIP当作master时如何使用。 新建Vivado工程&#xff0c;并新建block design&#xff0c;命…
最新文章