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

news2024/9/19 15:47:23

最近看博客又看到了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.coloradmin.cn/o/816143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis小记_one

目录 什么是框架 1.框架的概述 2.框架要解决的问题 3. 软件开发的分层重要性 4.分层开发的常见框架 MyBatis 框架概述 JDBC 编程的回顾 JDBC 问题分析 MyBatis 框架快速入门 1.官网下载MyBatis框架jar包 2.搭建MyBatis 开发环境 3. 编写持久层接口的映射文件 IUserD…

Stable Diffusion 使用教程

环境说明: stable diffusion version: v1.5.1python: 3.10.6torch: 2.0.1cu118xformers: N/Agradio: 3.32.0 1. 下载 webui 下载地址: GitHub stable-diffusion-webui 下载 根据自己的情况去下载: 最好是 N 卡:(我的…

计数排序算法

计数排序 计数排序说明: 计数排序(Counting Sort)是一种非比较性的排序算法,它通过统计元素出现的次数,然后根据元素出现的次数将元素排列在正确的位置上,从而实现排序。计数排序适用于非负整数或者具有确…

使用vue creat搭建项目

一、查看是否安装node和npm(显示版本号说明安装成功) node -v npm -v 显示版本号说明安装成功,如果没有安装,则需要先安装。 二、安装vue-cli脚手架 查看安装的版本(显示版本号说明安装成功) vue -V 三…

纯JS+Vue实现一个仪表盘

在使用canvas的时候发现数值变化&#xff0c;每次都要重新渲染&#xff0c;值都从0开始&#xff0c;这和我的需求冲突。 1. 先绘制基本的圆环背景&#xff0c;利用border-color和border-radius将正方形变成基本的圆环。 <div class"circle"><div class&qu…

使用toad对数据进行分箱处理

Toad 是专为工业界模型开发设计的Python工具包&#xff0c;特别针对评分卡的开发。Toad 的功能覆盖了建模全流程&#xff0c;从 EDA、特征工程、特征筛选到模型验证和评分卡转化。Toad 的主要功能极大简化了建模中最重要最费时的流程&#xff0c;即特征筛选和分箱。 导入模型包…

7 网络通信(上)

文章目录 网络通信概述ip地址ip的作用ip地址的分类私有ip 掩码和广播地址 linux 命令&#xff08;ping ifconfig&#xff09;查看或配置网卡信息&#xff1a;ifconfig(widows 用ipconfig)测试远程主机连通性&#xff1a;ping路由查看 端口端口是怎样分配的知名端口动态端口 查看…

思维导图在线生成,新手必备!

思维导图是一个很好的学习和工作的方式&#xff0c;可以解决我们工作中的很多困难的问题&#xff0c;但是现在随着思维导图学习方法的推广&#xff0c;市面上的导图软件层出不穷&#xff0c;电子化的思维导图软件极大的方便了我们的工作和生活&#xff0c;下面我们就一起来盘点…

Linux下Pycharm安装

查看java版本&#xff0c;如果没有安装&#xff0c;需要先安装Java JDK。 java -versionsudo apt install openjdk-11-jre-headless下载Pycharm社区般&#xff0c;安装。 tar -zxvf pycharm-community-2023.2.tar.gz sh /opt/software/pycharm-community-2023.2/bin/pycharm.s…

URL存储解锁数据管理的新思路,重新定义数据传输与共享(@vue/repl)

Thinking系列&#xff0c;旨在利用10分钟的时间传达一种可落地的编程思想。 近日&#xff0c;在了解 vue/repl 相关内容&#xff0c;其通过 URL 进行数据存储&#xff0c;感觉思路惊奇&#xff0c;打开了新方式。 首先&#xff0c;通过 URL 存储最大的便利是&#xff1a;无需服…

IDEA中连接虚拟机 管理Docker

IDEA中连接虚拟机 管理Docker &#x1f4d4; 千寻简笔记介绍 千寻简笔记已开源&#xff0c;Gitee与GitHub搜索chihiro-notes&#xff0c;包含笔记源文件.md&#xff0c;以及PDF版本方便阅读&#xff0c;且是用了精美主题&#xff0c;阅读体验更佳&#xff0c;如果文章对你有帮…

android 如何分析应用的内存(十三)——perfetto

android 如何分析应用的内存&#xff08;十三&#xff09; 本篇文章是native内存的最后一篇文章——perfetto perfetto简介 从2018年始&#xff0c;android开发者峰会正式推出perfetto工具。从此perfetto成为安卓最重要的工具之一。在2018年以前&#xff0c;android使用syst…

率失真优化

文章目录 率失真优化率失真优化技术率失真理论1.互信息量2.失真度3.率失真函数4.率失真信源编码定理 视频编码中的率失真优化1.视频失真测度2.视频率失真曲线3.视频编码率失真优化 率失真优化 编码比特率和失真度相互制约、相互矛盾 因此&#xff0c;视频编码的主要目的就是在…

浅析Java中的内存泄漏

浅析Java中的内存泄漏 Java最明显的一个优势就是它的内存管理机制。你只需简单创建对象&#xff0c;java的垃圾回收机制负责分配和释放内存。然而情况并不像想像的那么简单&#xff0c;因为在Java应用中经常发生内存泄漏。 本教程演示了什么是内存泄漏&#xff0c;为什么会发生…

CAN转ETHERCAT网关can协议是什么意思

大家好&#xff0c;今天要跟大家分享一款自主研发的通讯网关&#xff0c;JM-ECT-CAN。这款产品能够将各种CAN总线和ETHERCAT网络连接起来&#xff0c;实现高效的数据传输和通信。那么&#xff0c;这款通讯网关具体有哪些功能和特点呢&#xff1f;接下来&#xff0c;我们就一起来…

vscode配置c++环境

第一步&#xff1a;安装vscode编辑器 预先安装&#xff1a; vscode&#xff08;https://code.visualstudio.com/&#xff09;在vscode中安装 C/C extension for VS Code&#xff08;在左侧扩展栏中搜索 “C”&#xff09; 第二步&#xff1a;安装MinGW-w64工具链 MinGW 提供…

web浏览器脚本的调试

水一贴。 在浏览器中按F12点击"source"或者"源程序"点击html、js、css等源码文件所在的窗口的左边&#xff0c;此时点击处显示为蓝色光标&#xff0c;表示断点中断已经设置完毕。配合窗口右上角的"继续" “下一步” "跳过"等控制按钮…

计算机SCI期刊,和计算机会议哪个更权威? - 易智编译EaseEditing

在计算机学科领域&#xff0c;SCI期刊和计算机会议都有其特点和优势&#xff0c;但两者在权威性方面可能存在一些差异。 SCI期刊是指被SCI&#xff08;Science Citation Index&#xff09;收录的学术期刊&#xff0c;SCI是Web of Science&#xff08;科学引文索引&#xff09;的…

[内测招募] IDEA 插件 X-ChatGPT 内测预览版 支持自定义 ChatGPT 回调函数 释放 AI 的无限可能性

X-ChatGPT 独创的 [项目感知] 功能 打造更精准、更智能、更懂你 的专属 ai 编程助手 这个插件是一款基于开源项目 ChatGPT-Next-Web的 IntelliJ IDEA 平台的插件 价格 &#xff1a;免费、速率限制 每小时/100 次/ip 使用方式 &#xff1a;在 IDEA 插件商店中搜索 X-ChatGPT…

信号三表block,pending、handler

目录 前序&#xff1a; 信号流程图&#xff1a; pending表&#xff08;信号未决表 block表&#xff08;信号阻塞表 handler表&#xff08;信号递达表 小知识点 1&#xff1a;handler保存的是什么 前序&#xff1a; 进程信号中的三大表格 首先在了解进程信号中的三大表格…