【JAVA】io流之缓冲流
①BufferedInputStream、BufferedOutputStream(适合读写非普通文本文件)
②BufferedReader、BufferedWriter(适合读写普通文本文件。)
缓冲流的读写速度快,原理是:在内存中准备了一个缓存。读的时候从缓存中读。写的时候将缓存中的数据一次写出。都是在减少和磁盘的交互次数。
一、如何理解缓冲区?
家里盖房子,有一堆砖头要搬在工地100米外,单字节的读取就好比你一个人每次搬一块砖头,从堆砖头的地方搬到工地,这样肯定效率低下。
然而聪明的人类会用小推车,每次先搬砖头搬到小车上,再利用小推车运到工地上去,这样你再从小推车上取砖头是不是方便多了呀!这样效率就会大大提高,缓冲流就好比我们的小推车,给数据暂时提供一个可存放的空间。
二·、BufferedInputStream
FileInputStream/FileOutputStream是节点流
BufferedInputStream是缓冲流(包装流/处理流)。这个流的效率高。自带缓冲区。并且自己维护这个缓冲区。读大文件的时候建议采用这个缓冲流来读取。
关闭流只需要关闭最外层的处理流即可,通过源码就可以看到,当关闭处理流时,底层节点流也会关闭。
1.概述
BufferedInputStream
为另一个输入流添加了缓冲功能,它内部维护了一个缓冲区,当从流中读取数据时,会尽可能多地将数据读入缓冲区,这样后续的读取操作就可以直接从缓冲区中获取数据,而不必每次都从底层输入流中读取,从而减少了实际的 I/O 操作次数,提高了读取效率。
2.常用构造方法
BufferedInputStream(InputStream in)
:创建一个BufferedInputStream
,并使用默认大小的缓冲区。参数in
是要被缓冲的底层输入流。例如
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;/*** 1. java.io.BufferedInputStream的用法和FileInputStream用法相同。** 2. 他们的不同点是:* FileInputStream是节点流。* BufferedInputStream是缓冲流(包装流/处理流)。这个流的效率高。自带缓冲区。并且自己维护这个缓冲区。读大文件的时候建议采用这个缓冲流来读取。** 3. BufferedInputStream对 FileInputStream 进行了功能增强。增加了一个缓冲区的功能。** 4. 怎么创建一个BufferedInputStream对象呢?构造方法:* BufferedInputStream(InputStream in)**/
public class BufferedInputStreamTest1 {public static void main(String[] args) {BufferedInputStream bis = null;try {// 创建节点流//FileInputStream in = new FileInputStream("file.txt");// 创建包装流//bis = new BufferedInputStream(in);// 组合起来写bis = new BufferedInputStream(new FileInputStream("file.txt"));// 读,和FileInputStream用法完全相同byte[] bytes = new byte[1024];int readCount = 0;while((readCount = bis.read(bytes)) != -1){System.out.print(new String(bytes, 0, readCount));}} catch (Exception e) {e.printStackTrace();} finally {// 包装流以及节点流,你只需要关闭最外层的那个包装流即可。节点流不需要手动关闭。if (bis != null) {try {bis.close();} catch (IOException e) {e.printStackTrace();}}}}
}
在根路径下创建file.txt
运行结果:
⑵.BufferedInputStream(InputStream in, int size):
创建一个BufferedInputStream,并指定缓冲区的大小为size字节。例如:
FileInputStream fis = new FileInputStream("test.txt");
BufferedInputStream bis = new BufferedInputStream(fis, 8192);
read
方法主要功能是通过预加载数据到内存缓冲区,减少底层 I/O 操作的次数
三、BufferedOutputStream
常用构造方法 BufferedOutputStream(OutputStream out):创建一个BufferedOutputStream,并使用默认大小的缓冲区。参数out是要被缓冲的底层输出流。例如:
FileOutputStream fos = new FileOutputStream("test.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
BufferedOutputStream(OutputStream out, int size):创建一个BufferedOutputStream,并指定缓冲区的大小为size字节。例如:
FileOutputStream fos = new FileOutputStream("test.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos, 8192);
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*** 1. java.io.BufferedOutputStream也是一个缓冲流。属于输出流。* 2. 怎么创建BufferedOutputStream对象?* BufferedOutputStream(OutputStream out)* 3. FileOutputStream是节点流。 BufferedOutputStream是包装流。*/
public class BufferedOutputStreamTest01 {public static void main(String[] args) {BufferedOutputStream bos = null;try {bos = new BufferedOutputStream(new FileOutputStream("file.txt"));bos.write("你好,世界".getBytes());// 缓冲流需要手动刷新。bos.flush();} catch (Exception e) {e.printStackTrace();} finally {if (bos != null) {try {// 只需要关闭最外层的包装流即可。bos.close();} catch (IOException e) {e.printStackTrace();}}}}
}
运行结果:
四、使用BufferedInputStream 和BufferedOutputStream完成文件的复制
/*** 使用BufferedInputStream BufferedOutputStream完成文件的复制。*/
public class BufferedInputOutputStreamCopy {public static void main(String[] args) {long begin = System.currentTimeMillis();try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\86178\\Desktop\\2024\\test3.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\86178\\Desktop\\2024\\testwriter.txt"))){// 一边读一边写byte[] bytes = new byte[1024];int readCount = 0;while((readCount = bis.read(bytes)) != -1){bos.write(bytes, 0, readCount);}// 手动刷新bos.flush();} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}long end = System.currentTimeMillis();System.out.println("带有缓冲区的拷贝耗时"+(end - begin)+"毫秒"); // 671}
}
五、缓存流的mark与reset
输入流中的 mark
和 reset
(以 BufferedInputStream
为例)
1. 方法说明
void mark(int readlimit)
:在流的当前位置设置一个标记。readlimit
参数指定了在标记位置失效之前可以读取的最大字节数。也就是说,在读取了readlimit
个字节之后,标记可能会失效,此时调用reset
方法可能会抛出IOException
。void reset()
:将流的位置重置到之前通过mark
方法设置的标记位置。如果标记已经失效(例如,已经读取超过readlimit
个字节),则会抛出IOException
。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;public class BufferedInputStreamMarkResetExample {public static void main(String[] args) {try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.txt"))) {// 读取前 3 个字节int data;for (int i = 0; i < 3; i++) {data = bis.read();if (data != -1) {System.out.print((char) data);}}// 设置标记,允许在读取 10 个字节内重置到该位置bis.mark(10);// 继续读取 3 个字节for (int i = 0; i < 3; i++) {data = bis.read();if (data != -1) {System.out.print((char) data);}}// 重置到标记位置bis.reset();// 再次从标记位置读取 3 个字节for (int i = 0; i < 3; i++) {data = bis.read();if (data != -1) {System.out.print((char) data);}}} catch (IOException e) {e.printStackTrace();}}
}
运行结果:
输出流中的 mark
和 reset
在 BufferedOutputStream
中,并没有直接提供 mark
和 reset
方法。这是因为输出流的主要目的是将数据写入目标,而不是像输入流那样可以灵活地回退读取。一旦数据被写入输出流,通常是不可逆的操作。
不过,如果你需要实现类似的功能,可以考虑使用一些辅助的数据结构(如 ByteArrayOutputStream
)来缓存数据,然后根据需要重新写入。
相关文章:

【JAVA】io流之缓冲流
①BufferedInputStream、BufferedOutputStream(适合读写非普通文本文件) ②BufferedReader、BufferedWriter(适合读写普通文本文件。) 缓冲流的读写速度快,原理是:在内存中准备了一个缓存。读的时候从缓存中…...
from flask_session import Session 为什么是Session(app)这么用?
在 Flask 中,from flask_session import Session 和 Session(app) 的用法是为了配置和使用 Flask-Session 扩展,将用户的会话(Session)数据存储到服务器端(如 Redis、数据库或文件系统),而不是默…...

AI赋能的未来城市:如何用智能化提升生活质量?
这会是我们憧憬的未来城市吗? 随着技术的不断进步和城市化进程的加速,现代城市面临着诸多挑战——交通拥堵、环境污染、能源消耗、人口老龄化等问题愈发突出。为了应对这些挑战,建设智慧城市已成为全球发展的重要趋势。在这一进程中…...

【Go】Go wire 依赖注入
1. wire 简介 wire 是一个 Golang 的依赖注入框架(类比 Spring 框架提供的依赖注入功能) ⭐ 官方文档:https://github.com/google/wire 这里关乎到编程世界当中一条好用的设计原则:A用到了B,那么B一定是通过依赖注入的…...

深度集成DeepSeek与Java开发:智能编码新纪元全攻略 [特殊字符]
一、DeepSeek:Java开发者的第二大脑 🧠 1.1 传统开发痛点VS智能开发体验 传统开发DeepSeek智能辅助效率提升对比手动编写重复代码一键生成模板代码代码量减少70%↑调试全靠断点日志智能定位缺陷根源问题排查时间缩短60%↓文档维护耗时费力自动生成更新…...

WEB前端将指定DOM生成图片并下载最佳实践(html2canvas)
前言: html2canvas 是一个 JavaScript 库,其主要作用是将 HTML 元素或其部分内容渲染为 Canvas 图像。通过它,开发者可以将网页中的任意 DOM 元素(包括文本、图片、样式等)转换为图片格式(如 PNG 或 JPEG&…...

掌握.NET Core后端发布流程,如何部署后端应用?
无论你是刚接触.NET Core的新手还是已有经验的开发者,在这篇文章中你将会学习到一系列实用的发布技巧与最佳实践,帮助你高效顺利地将.NET Core后端应用部署到生产环境中 目录 程序发布操作 Docker容器注册表 文件夹发布 导入配置文件 网站运行操作 …...

深度学习学习笔记(34周)
目录 摘要 Abstracts 简介 Hourglass Module(Hourglass 模块) 网络结构 Intermediate Supervision(中间监督) 训练过程细节 评测结果 摘要 本周阅读了《Stacked Hourglass Networks for Human Pose Estimation》…...
C++ 设计模式-备忘录模式
游戏存档实现,包括撤销/重做、持久化存储、版本控制和内存管理 #include <iostream> #include <memory> #include <deque> #include <stack> #include <chrono> #include <fstream> #include <sstream> #include <ct…...

TOGAF之架构标准规范-信息系统架构 | 应用架构
TOGAF是工业级的企业架构标准规范,信息系统架构阶段是由数据架构阶段以及应用架构阶段构成,本文主要描述信息系统架构阶段中的应用架构阶段。 如上所示,信息系统架构(Information Systems Architectures)在TOGAF标准规…...

第一届网谷杯
统计四场的所有题目(共计12题,四场比赛一共上了21题【包括换题】) 随便记记,以免老题复用(已经复用了) Web 文件包含 1 伪协议 http://120.202.175.143:8011/?cphp://filter/convert.base64-encode/reso…...

Linux(ubuntu) GPU CUDA 构建Docker镜像
一、创建Dockerfile FROM ubuntu:20.04#非交互式,以快速运行自动化任务或脚本,无需图形界面 ENV DEBIAN_FRONTENDnoninteractive# 安装基础工具 RUN apt-get update && apt-get install -y \curl \wget \git \build-essential \software-proper…...

mysql -DQL语句和DCL语句
DQL 数据查询语言(Data Query Language,DQL)是数据库操作语言的重要组成部分,主要用于从数据库中检索数据,核心关键字为SELECT。以下从语法结构、常见操作及示例等方面详细介绍: 语法结构 DQL 的标准语法…...
掌握 ElasticSearch 组合查询:Bool Query 详解与实践
掌握 ElasticSearch 组合查询:Bool Query 详解与实践 一、引言 (Introduction)二、Bool 查询基础2.1 什么是 Bool 查询?2.2 Bool 查询的四种子句2.3 语法结构 三、Bool 查询的四种子句详解与示例3.1 must 子句3.2 filter 子句3.3 should 子句3.4 must_no…...

C++ 类和对象(友元、内部类、匿名对像)
目录 一、前言 二、正文 1.友元 1.1友元函数的使用 1.1.1外部友元函数可访问类的私有成员,友员函数仅仅是一种声明,他不是类的成员函数。 1.1.2一个函数可以是多个类的友元函数 2.友元类的使用 2.1什么是友元类 2.2 友元类的关系是单向的&#x…...
PostgreSQL 常用函数
PostgreSQL 常用函数 在数据库管理系统中,函数是执行特定任务的基本构建块。PostgreSQL 是一个功能强大的开源关系数据库管理系统,提供了丰富的内置函数,这些函数极大地增强了数据库操作的能力。以下是一些在 PostgreSQL 中常用的函数&#…...
掌握 ElasticSearch 四种match查询的原理与应用
文章目录 一、引言 (Introduction)二、准备工作:创建索引和添加示例数据三、match 查询四、match_all 查询五、multi_match 查询六、match_phrase 查询七、总结 (Conclusion) 一、引言 (Introduction) 在信息爆炸的时代,快速准确地找到所需信息至关重要…...

解决:Conda虚拟环境中未设置CUDA_HOME的问题
背景:我是Ubuntu22.04系统,最近在复现FoundationPose算法,按照README构建部署环境时,有一步一直卡住,看了下是未找到CUDA_HOME这个环境变量。 网上搜了下这个错误,需要设置CUDA_HOME的环境变量路径&#x…...

easyexcel和poi同时存在版本问题,使用easyexcel导出excel设置日期格式
这两天在使用easyexcel导出excel的时候日期格式全都是字符串导致导出的excel列无法筛选 后来调整了一下终于弄好了,看一下最终效果 这里涉及到easyexcel和poi版本冲突的问题,一直没搞定,最后狠下心来把所有的都升级到了最新版,然…...

HarmonyOS 开发套件 介绍——下篇
HarmonyOS 开发套件 介绍——下篇 在HarmonyOS的生态中,开发套件作为支撑整个系统发展的基石,为开发者提供了丰富而强大的工具和服务。本文将深入继续介绍HarmonyOS SDK、ArkCompiler、DevEco Testing、AppGallery等核心组件,帮助开发者全面掌…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...