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

IO模型与NIO基础二

抽象基类之二

FilterInputStream

         FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。
它的常用的子类有BufferedInputStream和DataInputStream
(1) BufferedInputStream的作用就是为“输入流提供缓冲功能,以及mark()和reset()功能”。

  1. InputStream和Reader提供的一些移动指针的方法:
  2. void mark(int readlimit ); 在记录指针当前位置记录一个标记(mark)。
  3. boolean markSupported(); 判断此输入流是否支持mark()操作,即是否支持记录标记。
  4. void reset(); 将此流的记录指针重新定位到上一次记录标记(mark)的位置。
  5. long skip(long n); 记录指针向前移动n个字节/字符。

      readlimit 参数给出当前输入流在标记位置变为非法前允许读取的字节数。
       这句话的意思是说:mark就像书签一样,用于标记,以后再调用reset时就可以再回到这个mark过的地方。mark方法有个参数,通过这个整型参数,告诉系统,希望在读出多少个字符之前,这个mark保持有效。

      比如说mark(10),那么在read()10个以内的字符时,reset()操作指针可以回到标记的地方,然后重新读取已经读过的数据,如果已经读取的数据超过10个,那reset()操作后,就不能正确读取以前的数据了,mark()打标记已经失效,reset()会报错。

      但实际的运行情况却和JAVA文档中的描述并不完全相符。 有时候在BufferedInputStream类中调用mark(int readlimit)方法后,即使读取超过readlimit字节的数据,mark标记仍可能有效,仍然能正确调用reset方法重置。
事实上,mark在JAVA中的实现是和缓冲区相关的。只要缓冲区够大,mark后读取的数据没有超出缓冲区的大小,mark标记就不会失效。如果不够大,mark后又读取了大量的数据,导致缓冲区更新,原来标记的位置自然找不到了。
因此,mark后读取多少字节才失效,并不完全由readlimit参数确定,也和BufferedInputStream类的缓冲区大小有关。 如果BufferedInputStream类的缓冲区大小大于readlimit,在mark以后只有读取超过缓冲区大小的数据,mark标记才会失效。

public class test1 {public static void main(String[] args) throws IOException {byte[] b=new byte[] {1,2,3,4,5};//把数组转为数组输入流ByteArrayInputStream bais = new ByteArrayInputStream(b);//进行一次封装,封装时指定缓冲区大小,先指定2个字节大小BufferedInputStream bis = new BufferedInputStream(bais,2);//先读出第一个字节数据出来,指针会指向第二个字节即2上面System.out.println(bis.read());  // 1//现在指针在2上,打一个标记bis.mark(1);   //按官方文档来说,读第一个数据出来后,标记会失效,reset()方法会报错,事实上不会报错,经过测试,是缓冲区bis读三个数据时,//大小缓冲区大小,缓冲区装不下了,标记才有用。System.out.println(bis.read());  //2System.out.println(bis.read());  //3bis.reset();System.out.println(bis.read());  //2}}
----------------------------------------------------------------------------
1
2
3
2

当连续读三个数据时,缓冲区(2个字节大小)装不下,标记才会失效

public class test1 {public static void main(String[] args) throws IOException {byte[] b=new byte[] {1,2,3,4,5};//把数组转为数组输入流ByteArrayInputStream bais = new ByteArrayInputStream(b);//进行一次封装,封装时指定缓冲区大小,先指定2个字节大小BufferedInputStream bis = new BufferedInputStream(bais,2);//先读出第一个字节数据出来,指针会指向第二个字节即2上面System.out.println(bis.read());  // 1//现在指针在2上,打一个标记bis.mark(1);   //按官方文档来说,读第一个数据出来后,标记会失效,reset()方法会报错,事实上不会报错,经过测试,是缓冲区bis读三个数据时,//大小缓冲区大小,缓冲区装不下了,标记才有用。System.out.println(bis.read());  //2System.out.println(bis.read());  //3System.out.println(bis.read());  //4bis.reset();System.out.println(bis.read());  没有数据打印,并报错了}}
----------------------------------------------------------------------------
1
2
3
4
Exception in thread "main" java.io.IOException: Resetting to invalid markat java.io.BufferedInputStream.reset(Unknown Source)at cn.ybzy.io.filter.test1.main(test1.java:33)

不设标记,不重设定位正常读没问题

public class test1 {public static void main(String[] args) throws IOException {byte[] b=new byte[] {1,2,3,4,5};//把数组转为数组输入流ByteArrayInputStream bais = new ByteArrayInputStream(b);//进行一次封装,封装时指定缓冲区大小,先指定2个字节大小BufferedInputStream bis = new BufferedInputStream(bais,2);System.out.println(bis.read());  // 1System.out.println(bis.read());  //2System.out.println(bis.read());  //3System.out.println(bis.read());  //4System.out.println(bis.read());  //5}}

(2) DataInputStream 是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。
      应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据。

FilterOutputStream

      FilterOutputStream 的作用是用来“封装其它的输出流,并为它们提供额外的功能”。
它主要包括BufferedOutputStream, DataOutputStream和PrintStream。
(1) BufferedOutputStream的作用就是为“输出流提供缓冲功能”。
(2) DataOutputStream 是用来装饰其它输出流,将DataOutputStream和DataInputStream输入流配合使用,
“允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。

打印流PrintStream

      PrintStream是用来装饰其它输出流。它能为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
            打印流提供了非常方便的打印功能,可以打印任何类型的数据信息,例如:小数,整数,字符串。
      之前打印信息需要使用OutputStream但是这样,所有数据输出会非常麻烦,PrintStream可以把OutputStream类重新包装了一下,使之输出更方便。

public class PrintStreamTest {public static void main(String[] args) throws FileNotFoundException {FileOutputStream fos =new FileOutputStream("c:\\c.txt");PrintStream print=new PrintStream(fos);print.print("xiongshaowen");print.print(123);print.print(12.3);print.print(new Object());print.close();}}

在这里插入图片描述
格式化输出:
JAVA对PrintStream功能进行了扩充,增加了格式化输出功能。直接使用Print即可。但是输出的时候需要指定输出的数据类型。
在这里插入图片描述

public class PrintStreamTest {public static void main(String[] args) throws FileNotFoundException {FileOutputStream fos =new FileOutputStream("c:\\c.txt");PrintStream ps=new PrintStream(fos);/*print.print("xiongshaowen");print.print(123);print.print(12.3);print.println(new Object());print.close();*///格式打印int i = 10;String s="打印流";float f = 15.5f;ps.printf("整数 %d,字符串 %s,浮点数 %f",i,s,f);ps.println();ps.printf("整数 [%d],字符串 %s,浮点数 '%f'",i,s,f);ps.close();}}

在这里插入图片描述

推回输入流的使用

通常我们使用输入流的时候,我们读取输入流是顺序读取,当读取的不是我们想要的怎么办,又不能放回去,虽然我们可以使用程序做其他的处理来解决,但是Java提供了推回输入流来解决这个问题,
推回输入流可以做这样子的事情:将已经读取出来的字节或字符数组内容推回到推回缓冲区里面,
从而允许重复读取刚刚读取的我们不想要的东西之前内容

注意:当程序创建一个推回输入流时需要指定推回缓冲区的大小,默认的推回缓冲区长度为一,
如果程序推回到推回缓冲区的内容超出了推回缓冲区的大小,将会引发Pushback buffer overflow 异常。
程序举例:
    假如C盘下有一个aa.txt文件,内容如下:我现在只想读取aaa前面的内容,后面的我不想要。
在这里插入图片描述

public class TuiHuistream {public static void main(String[] args) throws IOException {//1文件流,2字符流 3输入流Reader reader = new FileReader("C:\\aa.txt");PushbackReader pr = new PushbackReader(reader,1024);//从输入流中读取数据char[] cs = new char[5];int hasReadCount = 0;String sumString="";int count=0;                       //计数器,看看下面读了多少次数据while((hasReadCount=pr.read(cs))!=-1) {String curString = new String(cs,0,hasReadCount);sumString =sumString+curString;count++;int aaaIndex = sumString.indexOf("aaa");   //这里我们以'aaa’为标记,推回aaa之前的内容到缓冲区中if(aaaIndex>-1) {pr.unread(sumString.toCharArray());    //把所有内容推到缓冲区中(cs)//重新把我想要的内容(即aaa之前的内容)读出来if(aaaIndex >5) {cs = new char[aaaIndex];//扩容缓冲区}pr.read(cs,0,cs.length);System.out.println("我想要的内容为:"+new String(cs));break;}else {System.out.println(new String(cs));}}System.out.println("一共读了多少次:"+count+"次");pr.close();}}
------------------------------------------------------------------------------------------------------------------------------
ccccc
ccccc
ccccc
cc
c
cccca
我想要的内容为:ccccccccccccccccc
ccccc
一共读了多少次:6

相关文章:

IO模型与NIO基础二

抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能,以及mark()和res…...

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)

单例模式 作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全,调用效率高 ,但是不能延迟加载懒汉式线程安全,调用效率不高,能延迟加载双重检…...

T-SQL语言的数据库交互

T-SQL语言的数据库交互 引言 随着信息技术的不断发展,数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL(Transact-SQL)作为微软SQL Server的重要扩展语言&#xf…...

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)

inode 和 block 的映射 该博文中有详细解释:【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题: 问题一: 我们访问文件,都是用的文件名,没用过 inode 号啊? 之前总是说可以通过一个…...

慧集通(DataLinkX)iPaaS集成平台-业务建模之域

通过左侧导航菜单〖业务建模〗→〖域〗,进入该界面;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面,点击【新建】按钮进入新建页面;输入编码,名称、模块以及对应数据类…...

【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题

【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络,通过对抗生成网络生成少数类样本,平衡欺诈数据中正类样本极…...

android wifi framework与wpa_supplicant的交互

android frmework直接与wpa_supplicant进行交互,使用aidl或者hidl 二、事件 framework注册事件的地方: packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...

初学stm32 --- flash模仿eeprom

目录 STM32内部FLASH简介 内部FLASH构成(F1) FLASH读写过程(F1) 闪存的读取 闪存的写入 内部FLASH构成(F4 / F7 / H7) FLASH读写过程(F4 / F7 / H7) 闪存的读取 闪存的写入 …...

使用C语言实现栈的插入、删除和排序操作

栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...

C语言程序环境和预处理详解

本章重点: 程序的翻译环境 程序的执行环境 详解:C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...

基于机器学习随机森林算法的个人职业预测研究

1.背景调研 随着信息技术的飞速发展,特别是大数据和云计算技术的广泛应用,各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式,为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步,如深度学习、强化学习等…...

三种文本相似计算方法:规则、向量与大模型裁判

文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度:  比如,RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数,返回前TopK个候选文本。  在评估大模型生成的文本阶段,也需要评估…...

Python语言的计算机基础

Python语言的计算机基础 绪论 在当今信息技术飞速发展的时代,编程已经成为了一种必备技能。Python凭借其简洁、易读和强大的功能,逐渐成为初学者学习编程的首选语言。本文将以Python语言为基础,探讨计算机科学的基本概念,并帮助…...

Dify应用-工作流

目录 DIFY 工作流参考 DIFY 工作流 2025-1-15 老规矩感谢参考文章的作者,避免走弯路。 2025-1-15 方便容易上手 在dify的一个桌面上,添加多个节点来完成一个任务。 每个工作流必须有一个开始和结束节点。 节点之间用线连接即可。 每个节点可以有输入和输出 输出类型有,字符串,…...

02.02、返回倒数第 k 个节点

02.02、[简单] 返回倒数第 k 个节点 1、题目描述 实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。 2、题解思路 本题的关键在于使用双指针法,通过两个指针(fast 和 slow),让 fast 指针比 slow 指针…...

Linux手写FrameBuffer任意引脚驱动spi屏幕

一、硬件设备 开发板:香橙派 5Plus,cpu:RK3588,带有 40pin 外接引脚。 屏幕:SPI 协议 0.96 寸 OLED。 二、需求 主要是想给板子增加一个可视化的监视器,并且主页面可调。 平时跑个模型或者服务,…...

怎么修复损坏的U盘?而且不用格式化的方式!

当你插入U盘时,若电脑弹出“需要格式化才能使用”提示,且无法打开或读取其中的数据,说明U盘极有可能已经损坏。除此之外,若电脑在连接U盘后显示以下信息,也可能意味着U盘出现问题,需要修复损坏的U盘&#x…...

语音技术在播客领域的应用(2)

播客是以语音为主,各种基于AI 的语音技术在播客领域十分重要。 语音转文本 Whisper Whisper 是OpenAI 推出的开源语音辨识工具,可以把音档转成文字,支援超过50 种语言。这款工具是基于68 万小时的训练资料,其中包含11.7 万小时的…...

【Linux】应用层自定义协议与序列化

🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 应用层 🦋 再谈 "协议"🦋 网络版计算器🦋 序列化 和 反序列化 二:🔥 重新理解 read、…...

深度学习中的张量 - 使用PyTorch进行广播和元素级操作

深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思? 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作,它作用于各自张量中的相应元素…...

全面掌握ESP WiFi中继器DHCP服务器配置:高效管理嵌入式设备网络

全面掌握ESP WiFi中继器DHCP服务器配置:高效管理嵌入式设备网络 【免费下载链接】esp_wifi_repeater A full functional WiFi Repeater (correctly: a WiFi NAT Router) 项目地址: https://gitcode.com/gh_mirrors/es/esp_wifi_repeater ESP WiFi中继器是一款…...

AI辅助开发:打造你的智能编程技能教练——基于快马平台实践

最近在学编程时,发现一个痛点:遇到问题经常要反复查文档、搜论坛,效率很低。刚好体验了InsCode(快马)平台的AI辅助功能,用它做了个"智能编程教练"的小项目,效果意外地好。分享下具体实现思路和实际体验&…...

Cisco Packet Tracer新手必看:5分钟搞定路由器静态路由配置(附避坑指南)

Cisco Packet Tracer静态路由配置实战:从零到精通的完整指南 刚接触网络工程的朋友们,第一次在Cisco Packet Tracer中配置静态路由时,是不是经常遇到"网络不通"的困扰?作为网络通信的基础技能,静态路由配置看…...

USB2.0供电那些事儿:为什么你的外设总是供电不足?

USB2.0供电困境解析:从原理到实践的全面解决方案 当你的移动硬盘突然断开连接,或者外接键盘间歇性失灵时,很可能正遭遇USB2.0供电不足的经典难题。这种看似简单的接口背后,隐藏着复杂的电力分配机制与设备兼容性博弈。本文将带你穿…...

PDF-Parser-1.0智能办公:告别手动复制粘贴的PDF处理方案

PDF-Parser-1.0智能办公:告别手动复制粘贴的PDF处理方案 1. 为什么需要智能PDF解析工具 在日常办公场景中,PDF文档处理是一个高频且痛苦的工作环节。根据统计,职场人士平均每周需要处理15-20份PDF文件,包括合同、报告、发票等各…...

RTX4090D显存优化:OpenClaw长文本处理实测Qwen3-32B性能

RTX4090D显存优化:OpenClaw长文本处理实测Qwen3-32B性能 1. 测试背景与实验设计 去年我在处理学术论文时,经常遇到需要分析几十页PDF的情况。传统工具要么截断文本,要么丢失关键上下文。当我发现OpenClaw支持本地部署大模型后,立…...

墨语灵犀开源模型生态:对接LangChain/RAG构建专属翻译知识库

墨语灵犀开源模型生态:对接LangChain/RAG构建专属翻译知识库 1. 引言:当古典美学遇见现代AI架构 在人工智能技术快速发展的今天,翻译工具已经从简单的词汇转换演变为理解文化语境和语义深度的智能系统。「墨语灵犀」作为基于腾讯混元大模型…...

家常饺子·每家不一样

你家的馅,和我家的不一样 1. 食材清单(家家都有) 食材分类具体材料分量备注皮面粉3碗买现成的饺子皮也行水适量和面用馅猪肉馅1斤肥瘦三七开白菜或韭菜1把看你家爱吃什么姜末一点点葱花一小把盐1勺生抽1勺香油几滴 2. 核心步骤:…...

告别单行输入:在Python IDLE Shell中轻松编辑多行代码的完整指南

告别单行输入:在Python IDLE Shell中轻松编辑多行代码的完整指南 对于Python初学者来说,IDLE Shell是一个既熟悉又陌生的存在。熟悉是因为它随Python安装包默认提供,陌生则源于大多数人仅将其视为简单的交互式命令行工具。实际上,…...

医疗陪护管理系统:信息化管理在医院的应用

博主介绍: 所有项目都配有从入门到精通的安装教程,可二开,提供核心代码讲解,项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频; 项目的界面和功能都可以定制,包安装运行&#xf…...