当前位置: 首页 > news >正文

BIO/NIO学习

在传送文件的时候常常出现这么一个问题,就是当客户端的文件全部传送完了之后,服务器没有接收到客户端那边传过的停止信号,所以服务器也就跟着客户端停止运行了,我们可以使用

  try {socket.shutdownOutput();} catch (IOException e) {throw new RuntimeException(e);}

这么一段代码使客户端的soket连接中断,这样就告诉了服务器那边 客户端已经运行完了

 

这三个输入流在 Java 中都用于从各种源(如文件、网络、内存等)中读取数据,但它们之间有一些区别:

  1. InputStream 是所有字节输入流的抽象类,它是字节输入流的基类。它提供了读取字节的基本方法,但是不能直接处理字符数据。

  2. InputStreamReader 是字节流到字符流的桥梁。它将字节流转换为字符流,可以指定编码方式,方便地读取字符数据。

  3. BufferedInputStream 是对输入流的缓冲,它实际上是一个装饰器模式的应用,用于提高输入流的读取效率。它通过在内存中建立一个缓冲区,减少了对磁盘的访问次数,提高了读取性能。

总结来说,InputStream 是字节输入流的抽象类,InputStreamReader 用于将字节流转换为字符流,而 BufferedInputStream 则是对输入流的缓冲,用于提高读取性能。

Buffer的主要作就是装入数据,然后输出数据,相当于一个竹筒,通过put方法放入数据,没放一些数据 Nuffer的position相应的就会向后移动一些位置。
  当Buffer装入这些数据结束后,条用Buffer的flip()方法,该方法将limit设置为position所在位置,评奖position设为0,这就是的Buffer的读写指针又移到了开始的位置,也就是卓,Buffer调用flip()方法之后,BUffer为输出数据做好准备,当Buffer输出数据结束之后,Buffer调用clear方法,clear()不是将Buffer里面的数据清空,它仅仅只是将position的位置设置为0,后面的数据会将position后面的数据覆盖,将limit设置为capacity,这样就为后面再一次装入数据做好准备

Buffer的样子

在这里需要区分rewind和flip方法

flip()rewind() 是 ByteBuffer 类中的两个重要方法,它们都用于在读写操作之间调整缓冲区的位置和限制。

  1. flip() 方法:

    • flip() 方法的作用是将缓冲区从写模式切换到读模式。在写模式下,通过 put() 方法向缓冲区写入数据时,position 会逐渐增加,limit 则保持不变。而在读模式下,准备从缓冲区中读取数据时,需要将 position 设置为 0,同时将 limit 设置为之前的 position,以限制读取的数据范围。
    • 具体来说,flip() 方法会将 limit 设置为当前 position,然后将 position 设置为 0,这样就完成了从写模式到读模式的切换
  2. rewind() 方法:

    • rewind() 方法的作用是将 position 设置为 0,以便重新读取缓冲区中的数据,而不影响 limit 的值。这意味着可以重复读取缓冲区中的数据,而不必改变 limit 的设定。
    • 通常情况下,rewind() 方法用于在再次读取先前写入的数据之前,将 position 设置为 0。

Channel可以直接将指定文件的部分或者全部直接映射成Buffer

文件在计算机中实际上是存储在磁盘上的,但在程序运行时,文件内容会被读取到计算机的内存中进行处理。当你打开一个文件时,操作系统会将文件的内容加载到内存中,以便程序可以直接从内存中读取和操作文件数据。

当你使用传统的文件 I/O 操作(比如使用InputStream和OutputStream)时,需要显式地将文件内容从磁盘读取到内存中,并且在写入文件时也需要将数据从内存写回到磁盘。这个过程涉及了磁盘 I/O 操作,而磁盘访问通常比内存访问要慢得多。

而通过NIO中的文件映射(FileChannel.map()方法),可以直接将文件的部分或全部内容映射到内存中的ByteBuffer中,从而实现基于内存的文件读写操作。这样可以避免传统的文件I/O操作,提高了文件I/O操作的性能和灵活性。

因此,无论是传统的文件 I/O 操作还是NIO中的文件映射,文件内容都会被加载到计算机的内存中进行处理。

非阻塞的NIO连接方式差不多是这个样子

相关文章:

  • JAVA面试题大全(十二)
  • 常见的MySQL语句类型及其基础用法
  • 高效写代码java-推荐插件1(格式转化 ConverterX )-日后待更新
  • 实时通信的方式——WebRTC
  • Mysql 备份恢复 mysqldump与xtrabackup备份
  • 6.8 LIBBPF API(七,bpf_core_read.h 函数,定义,枚举)
  • 自适应星空背景个人导航单页(附带源码)
  • 香橙派华为昇腾CANN架构编译opencv4.9
  • 大语言模型的工程技巧(三)——分布式计算
  • 【Python-OS】os.path.isfile()
  • 大工作量LUAD代谢重编程模型多组学(J Transl Med)
  • QT学习(20):QStyle和自定义样式
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • 再次学习History.scrollRestoration
  • 在Spring中自定义事件及发布与监听
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • Angular6错误 Service: No provider for Renderer2
  • dva中组件的懒加载
  • Java多线程(4):使用线程池执行定时任务
  • Linux后台研发超实用命令总结
  • maven工程打包jar以及java jar命令的classpath使用
  • Nodejs和JavaWeb协助开发
  • 创建一种深思熟虑的文化
  • 动态规划入门(以爬楼梯为例)
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 线性表及其算法(java实现)
  • 用mpvue开发微信小程序
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • # Java NIO(一)FileChannel
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #1014 : Trie树
  • #QT(智能家居界面-界面切换)
  • (02)Hive SQL编译成MapReduce任务的过程
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (2020)Java后端开发----(面试题和笔试题)
  • (35)远程识别(又称无人机识别)(二)
  • (5)STL算法之复制
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (C++17) optional的使用
  • (done) 声音信号处理基础知识(4) (Understanding Audio Signals for ML)
  • (PySpark)RDD实验实战——取一个数组的中间值
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (一)SvelteKit教程:hello world
  • (译)计算距离、方位和更多经纬度之间的点
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .NET项目中存在多个web.config文件时的加载顺序
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @vue/cli脚手架
  • [ Linux ] Linux信号概述 信号的产生
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [1159]adb判断手机屏幕状态并点亮屏幕