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

JAVA重点基础、进阶知识及易错点总结(14)字节流 字符流

Java 巩固进阶 · 第14天主题字节流 字符流 —— 文件读写的核心引擎 进度概览今天进入 IO 流的灵魂章节掌握这 4 个核心类你就能打通文件读写的任督二脉。 核心价值万能字节流InputStream/OutputStream处理图片/视频/任意二进制文件文件上传下载的基石。文本字符流Reader/Writer专为纯文本设计自动处理编码彻底告别中文乱码。资源安全try-with-resources语法自动关闭流杜绝资源泄漏生产环境红线。性能基石理解缓冲思想为明天学习高效流打下理论基础。一、流的分类一张图看懂选型逻辑 ️┌─ 字节流 (Byte Stream) ──► InputStream / OutputStream │ ├─ 万能能读任何文件图片/音频/视频/文本 │ ├─ 单位字节 (byte)8 位 │ └─ 场景文件复制、图片上传、网络传输 │ Java IO 流 ─────┤ │ ┌─ 字符流 (Char Stream) ──► Reader / Writer │ ├─ 专用只能读纯文本.txt/.java/.md/.yml │ ├─ 单位字符 (char)16 位 (Unicode) │ ├─ 核心优势内置编码转换防中文乱码 │ └─ 场景配置文件读取、日志写入、模板渲染 │ └─ 选型口诀 一切文件皆字节文本优先用字符 不确定时用字节永远不亏保平安 本质区别编码编码编码对比项字节流字符流处理单位byte(8 位)char(16 位, Unicode)编码感知❌ 无感知原样读写✅ 自动编解码 (默认平台编码)中文处理可能乱码需手动转码自动处理不易乱码适用文件所有文件二进制 文本仅纯文本文件父类InputStream/OutputStreamReader/Writer⚠️中文乱码根源// 字节流读中文如果编码不匹配必乱码FileInputStreaminnewFileInputStream(cn.txt);// 文件是 UTF-8byte[]bufnewbyte[1024];in.read(buf);StringtextnewString(buf);// ❌ 默认用平台编码(如GBK)解码 UTF-8 字节 → 乱码// ✅ 正确显式指定编码StringtextnewString(buf,StandardCharsets.UTF_8);// 字符流自动用指定编码解码推荐FileReaderfrnewFileReader(cn.txt);// 默认平台编码仍可能乱码// ✅ 最佳用 InputStreamReader 包装字节流显式指定编码InputStreamReaderisrnewInputStreamReader(newFileInputStream(cn.txt),StandardCharsets.UTF_8);二、字节流实战FileInputStream / FileOutputStream1. 读取文件三种姿势推荐缓冲 数组// ❌ 姿势1单字节读取慢100 次 IO不推荐FileInputStreaminnewFileInputStream(a.txt);intb;while((bin.read())!-1){// 每次读 1 字节System.out.print((char)b);}in.close();// ✅ 姿势2字节数组 缓冲快推荐⭐FileInputStreaminnewFileInputStream(a.txt);byte[]bufnewbyte[1024*8];// 8KB 缓冲平衡内存与效率intlen;while((lenin.read(buf))!-1){// len 是实际读取字节数// ⚠️ 关键必须用 0, len避免读取上次残留数据System.out.print(newString(buf,0,len,StandardCharsets.UTF_8));}in.close();// ✅✅ 姿势3try-with-resources NIO现代写法明天学2. 写入文件覆盖写 vs 追加写// 构造方法第二个参数true追加false/省略覆盖FileOutputStreamoutnewFileOutputStream(log.txt,true);// ✅ 追加模式// 写入字节数组out.write(Hello IO\n.getBytes(StandardCharsets.UTF_8));// 写入部分字节配合读取时的 len 使用byte[]dataPartial.getBytes();out.write(data,0,data.length);out.close();// ⚠️ 必须 close() 或 flush()否则数据可能滞留缓冲区3. 文件复制万能模板背下来/** * 通用文件复制方法支持任意文件图片/视频/文本 */publicstaticvoidcopyFile(Filesrc,Filedest)throwsIOException{// 1. 确保目标父目录存在Fileparentdest.getParentFile();if(parent!null!parent.exists()){parent.mkdirs();}// 2. try-with-resources 自动关流重点try(FileInputStreaminnewFileInputStream(src);FileOutputStreamoutnewFileOutputStream(dest)){byte[]bufnewbyte[1024*16];// 16KB 缓冲性能与内存平衡intlen;while((lenin.read(buf))!-1){out.write(buf,0,len);// ⚠️ 关键只写实际读取的字节}// ✅ 无需手动 flush()/close()try-with-resources 自动处理}}为什么out.write(buf, 0, len)而不是out.write(buf)假设 buf 大小1024最后一次读取只读了 100 字节 - buf[0~99] 是新数据buf[100~1023] 是上次残留的旧数据 - 如果写整个 buf会多写 924 字节垃圾数据❌ - 正确只写 0~len-1 的有效数据 ✅三、字符流实战FileReader / FileWriter纯文本专用1. 读取文本自动解码但要注意默认编码陷阱// ⚠️ 陷阱FileReader 使用平台默认编码Windows 通常是 GBK// 如果文件是 UTF-8 编码中文可能乱码FileReaderfrnewFileReader(cn.txt);// 隐式用默认编码解码intch;while((chfr.read())!-1){System.out.print((char)ch);}fr.close();// ✅ 最佳实践用 InputStreamReader 包装字节流显式指定编码try(InputStreamReaderisrnewInputStreamReader(newFileInputStream(cn.txt),StandardCharsets.UTF_8)){char[]cbufnewchar[1024];intlen;while((lenisr.read(cbuf))!-1){System.out.print(newString(cbuf,0,len));}}2. 写入文本同样注意编码一致性// ⚠️ FileWriter 同样使用平台默认编码FileWriterfwnewFileWriter(out.txt,true);// 追加模式fw.write(你好世界\n);// 用平台编码编码字符fw.close();// ✅ 最佳OutputStreamWriter 显式编码try(OutputStreamWriteroswnewOutputStreamWriter(newFileOutputStream(out.txt,true),StandardCharsets.UTF_8)){osw.write(你好UTF-8 编码的世界\n);// osw.flush(); // 可手动刷新但 close() 会自动 flush} FileReader vs InputStreamReader 对比特性FileReaderInputStreamReader FileInputStream编码控制❌ 只能用平台默认编码✅ 可显式指定任意编码UTF-8/GBK 等跨平台❌ 可能因系统编码不同导致乱码✅ 编码固定行为一致推荐度⭐⭐仅测试/内部工具⭐⭐⭐⭐⭐生产环境首选SpringBoot 实践读取application.yml或模板文件时永远显式指定编码Value(classpath:templates/email.html)privateResourcetemplate;privateStringreadTemplate()throwsIOException{try(InputStreamistemplate.getInputStream();InputStreamReaderreadernewInputStreamReader(is,StandardCharsets.UTF_8)){returnStreamUtils.copyToString(reader);// Spring 工具类}}四、资源管理try-with-resources生产环境红线⚠️1. 为什么必须用// ❌ 传统写法异常时可能漏关流 → 资源泄漏 → 线上事故FileInputStreaminnull;try{innewFileInputStream(a.txt);// ... 业务逻辑if(error)return;// ⚠️ 提前返回close() 没执行}catch(IOExceptione){e.printStackTrace();}finally{if(in!null){try{in.close();}catch(IOExceptione){e.printStackTrace();}// 嵌套 try-catch代码臃肿}}// ✅ 现代写法自动关流代码简洁异常安全try(FileInputStreaminnewFileInputStream(a.txt)){// ... 业务逻辑// 无论正常返回还是抛出异常in.close() 都会自动调用}catch(IOExceptione){e.printStackTrace();// 只需处理业务异常}2. 使用条件 原理条件资源类必须实现java.lang.AutoCloseable接口所有 IO 流都实现了 ✅原理编译器自动生成finally块按声明逆序关闭资源多资源用分号;分隔关闭顺序后声明的先关闭// 多资源示例文件复制try(FileInputStreaminnewFileInputStream(src.txt);FileOutputStreamoutnewFileOutputStream(dest.txt)){// 先关 out再关 inbyte[]bufnewbyte[8192];intlen;while((lenin.read(buf))!-1){out.write(buf,0,len);}// ✅ 无需手动 flush/close}catch(IOExceptione){log.error(文件复制失败,e);// 生产环境用日志框架}关闭顺序为什么重要装饰者模式流如BufferedInputStream包装FileInputStream关闭外层流时会自动关闭内层流按逆序关闭确保缓冲数据先刷新到底层流五、 今日实战任务构建简易文件工具类任务1实现通用文件读取方法支持编码/** * 读取文件内容为字符串 * param file 文件 * param charset 字符编码如 UTF_8 * return 文件内容 */publicstaticStringreadFileToString(Filefile,Charsetcharset)throwsIOException{// TODO: 用 try-with-resources InputStreamReader 实现// 要求处理文件不存在、编码异常等边界情况}// 测试分别用 UTF-8 和 GBK 读取含中文的文件观察结果任务2实现安全文件复制带进度回调/** * 复制大文件时提供进度回调SpringBoot 上传常用 * param src 源文件 * param dest 目标文件 * param callback 进度回调 (current, total) - void */publicstaticvoidcopyFileWithProgress(Filesrc,Filedest,ProgressCallbackcallback)throwsIOException{// TODO:// 1. 用 16KB~64KB 缓冲数组// 2. 每复制一定字节如 10%调用 callback.progress(current, total)// 3. 处理目标文件已存在的场景覆盖/跳过/重命名}// 回调接口定义FunctionalInterfacepublicinterfaceProgressCallback{voidprogress(longcopied,longtotal);}任务3字符编码转换工具/** * 将文件从一种编码转换为另一种编码如 GBK → UTF-8 * param srcFile 源文件originalCharset 编码 * param destFile 目标文件targetCharset 编码 */publicstaticvoidconvertEncoding(FilesrcFile,FiledestFile,CharsetoriginalCharset,CharsettargetCharset)throwsIOException{// TODO: 用 InputStreamReader OutputStreamWriter 实现编解码转换// 挑战处理 BOM 头Byte Order Mark}任务4SpringBoot 集成小练习# application.ymlapp:file:upload-dir:./uploadsdefault-charset:UTF-8ServicepublicclassFileService{Value(${app.file.default-charset})privateStringdefaultCharset;/** * 上传文件保存并返回访问路径 * 要求 * 1. 校验文件扩展名白名单机制 * 2. 重命名文件UUID 原扩展名防覆盖 * 3. 用字节流复制上传内容 * 4. 记录文件元数据大小、编码、上传时间 */publicFileInfoupload(MultipartFilefile)throwsIOException{// TODO: 实现上传逻辑// 提示MultipartFile.getInputStream() 返回字节流}} 第14天 · 核心总结极简背诵版选型决策树要读/写的文件是 ├─ 图片/音频/视频/任意二进制 → 字节流 (InputStream/OutputStream) ├─ 纯文本 (.txt/.java/.yml) → 字符流 (Reader/Writer) └─ 不确定 → 用字节流 显式编码转换永远安全编码防坑指南字节流转字符串new String(bytes, Charset)必须指定编码字符流底层FileReader用平台默认编码生产环境建议用InputStreamReader 显式编码统一项目编码-Dfile.encodingUTF-8 编辑器保存为 UTF-8资源管理铁律✅ 永远用try-with-resources自动关流✅ 多资源用分号分隔关闭顺序后声明先关闭❌ 禁止手动close()放在try块末尾异常时可能不执行高性能复制模板背下来try(InputStreaminnewFileInputStream(src);OutputStreamoutnewFileOutputStream(dest)){byte[]bufnewbyte[16*1024];// 16KB 缓冲intlen;while((lenin.read(buf))!-1){out.write(buf,0,len);// ⚠️ 关键只写有效字节}}SpringBoot 实践点文件上传MultipartFile.getInputStream() 字节流复制配置读取Value ResourceInputStreamReader(UTF-8)日志写入FileWriter追加模式 自动轮转结合 Logback

相关文章:

JAVA重点基础、进阶知识及易错点总结(14)字节流 字符流

🚀 Java 巩固进阶 第14天 主题:字节流 & 字符流 —— 文件读写的核心引擎📅 进度概览:今天进入 IO 流的灵魂章节!掌握这 4 个核心类,你就能打通文件读写的任督二脉。 💡 核心价值&#xff…...

OpenClaw压力测试:Phi-3-mini-128k-instruct持续运行24小时稳定性报告

OpenClaw压力测试:Phi-3-mini-128k-instruct持续运行24小时稳定性报告 1. 测试背景与目标 上周在本地部署了OpenClawPhi-3-mini组合后,我一直在思考这套方案的稳定性边界。作为个人自动化助手,它能否胜任724小时不间断工作?当我…...

【Java低代码组件调试黄金法则】:20年架构师亲授5大高频故障定位技巧,90%开发者从未听说

第一章:Java低代码组件调试的本质与认知跃迁Java低代码平台并非屏蔽复杂性,而是将复杂性重新封装、可视化与可追溯化。调试低代码组件的本质,是穿透表层拖拽逻辑,定位其背后生成的Java字节码、Spring Bean生命周期行为、以及运行时…...

快速验证限流策略:用快马一键生成rate limit exceeded处理原型

快速验证限流策略:用快马一键生成rate limit exceeded处理原型 最近在开发一个需要调用第三方API的项目时,遇到了经典的"rate limit exceeded"问题。作为开发者我们都知道,API调用频率超限是系统设计中必须考虑的场景。传统从零搭…...

【限时开源】Polars 2.0清洗模板库V1.0发布:含金融时序对齐、电商ID映射、日志正则归一化等9大高复用Pipeline

第一章:Polars 2.0大规模数据清洗技巧入门到精通教程 Polars 2.0 是专为高性能、内存安全与并行计算设计的 DataFrame 库,其惰性执行引擎与零拷贝语义使其在处理 GB 级别结构化数据时显著优于 Pandas。本章聚焦真实场景下的数据清洗实践,涵盖…...

《B3845 [GESP样题 二级] 勾股数》

题目背景 对应的选择、判断题:https://ti.luogu.com.cn/problemset/1102 题目描述 勾股数是很有趣的数学概念。如果三个正整数 a,b,c,满足 a2b2c2,而且 1≤a≤b≤c,我们就将 a,b,c 组成的三元组 (a,b,c) 称为勾股数。你能通过编…...

气象数据可视化实战:从雷达图到三维风场,前端技术栈全解析

气象数据可视化实战:从雷达图到三维风场,前端技术栈全解析 气象数据的可视化一直是前端开发领域最具挑战性的方向之一。想象一下,当你需要将每小时更新的全球气象数据转化为直观的动态图像,让气象学家一眼就能看出台风路径、让飞行…...

构建企业级抓取服务:基于快马平台的openclaw生产环境部署实战

今天想和大家分享一个实战经验:如何用InsCode(快马)平台快速搭建企业级的openclaw分布式抓取服务。这个方案特别适合需要处理大规模数据采集的业务场景,比如电商价格监控、舆情分析或者竞品追踪。 分布式架构设计 生产环境最怕单点故障,所以我…...

学生信息管理系统--Python进阶项目

1.需求分析: ​需求:根据操作流程以及系统需求,完成面向对象版学生管理系统项目开发 ​a.可以显示基本的版本信息和操作界面; ​b.可以通过键盘输入信息来完成基本功能,例如选择序号、确认退出、添加学生、修改信息等; ​c.学生属性信息有姓名、性别、年…...

Mojo调用PyTorch模型推理却遭遇内存泄漏?——国家级实验室验证的4层内存隔离架构首次公开

第一章:Mojo调用PyTorch模型推理却遭遇内存泄漏?——国家级实验室验证的4层内存隔离架构首次公开在高性能AI边缘部署场景中,Mojo语言通过其零开销FFI机制调用PyTorch C前端(LibTorch)实现低延迟推理,但实测…...

告别‘空树’!用UIAutomation Client伪装无障碍工具,搞定新版微信自动化(附完整C#项目)

深度解析Windows UIAutomation在微信自动化中的高阶应用 微信作为国民级通讯工具,其PC端自动化一直是企业RPA和开发者关注的热点。随着微信4.1版本的更新,传统的UI自动化方案遭遇了重大挑战——UI树变得"空空如也"。这背后隐藏着怎样的技术原理…...

数字IC时序约束实战:深入解析clock_uncertainty的设置策略与后端影响

1. 时钟不确定度的本质与组成 刚入行数字IC设计时,我最头疼的就是时序约束里那些看似相似却又微妙差别的概念。记得第一次看到clock_uncertainty这个参数,我盯着综合报告里的红色违例发了半小时呆。后来才明白,这个参数就像给时钟信号加了&qu…...

多层PCB内部结构与HDI技术深度解析

1. 多层PCB内部结构全解析作为一名硬件工程师,第一次拆解十层PCB板时,那种震撼感至今难忘。密密麻麻的过孔像微型城市的地下管网,精密排布的走线如同错综复杂的立体交通网。今天我就用最直观的立体解剖图,带你看透各种叠层结构的P…...

Qt多线程数据库操作:安全分离连接,彻底解决段错误

在 Qt 开发中,数据库操作与多线程的搭配是一个经典难题。许多开发者都曾遇到过这样的诡异现象:程序运行一段时间后突然崩溃,堆栈指向数据库操作,但代码逻辑明明正确。真相只有一个——数据库连接被多个线程共享了。本文结合真实项…...

SecGPT-14B开源大模型部署:CSDN平台内开箱即用,省去HuggingFace下载环节

SecGPT-14B开源大模型部署:CSDN平台内开箱即用,省去HuggingFace下载环节 想快速体验一个专注于网络安全问答的14B大模型,但又不想经历从HuggingFace下载几十GB模型文件的漫长等待和复杂配置?现在,在CSDN星图平台上&am…...

Flash Memory技术解析与应用实践

1. Flash Memory技术全景解析作为一名嵌入式系统开发工程师,我使用Flash Memory已有十余年经验。从早期的NOR Flash烧录到现在的TLC NAND优化,这项技术始终是存储领域的核心支柱。让我们抛开教科书式的定义,从实际工程角度重新认识这项既熟悉…...

C++ 性能评测工程:基于 Google Benchmark 的 C++ 函数级性能基准测试方法论

各位技术同仁,下午好!今天,我们将深入探讨一个在C开发中至关重要的话题:C 函数级性能基准测试。尤其是在追求极致性能的C世界里,仅仅依靠经验和直觉来优化代码是远远不够的。我们需要一套科学、严谨的方法论来量化和评…...

【WEB模型】CS架构BS架构HTMLCSSJS

一、CS架构 - Client/Server 客户端/服务器pc安装软件:安卓应用、ios应用需要安装专门软件才能用,软件直接跟服务器通信开发成本高,各个平台都有对应的开发工程师好处:功能强大二、BS架构 - Browser/Server 浏览器/服务器不需要安…...

Windows平台OpenClaw部署:百川2-13B-4bits量化版调用详解

Windows平台OpenClaw部署:百川2-13B-4bits量化版调用详解 1. 为什么选择这个组合? 去年冬天,当我第一次尝试在Windows笔记本上部署本地AI助手时,遇到了显存不足的难题。我的GTX 3060显卡根本无法承载常规的13B模型,直…...

从STFT到ISTFT:窗函数、填充与流式处理的实战指南

1. 窗函数一致性:信号重建的隐形守护者 第一次用STFT处理语音信号时,我踩过一个典型坑:用汉宁窗做分析,却忘了在重建时指定相同窗函数。结果重建后的语音像被掐着脖子说话,高频部分全是毛刺。这个教训让我明白&#xf…...

基于vue的非遗文化传承平台[vue]-计算机毕业设计源码+LW文档

摘要:非物质文化遗产(非遗)作为民族文化的重要组成部分,承载着人类社会的文明和历史记忆。随着现代社会的快速发展,非遗文化的传承面临着诸多挑战。为了更好地保护和传承非遗文化,本文设计并实现了一个基于…...

DNMSI2C轻量级声级计驱动库:IEC标准SPL数据采集

1. 项目概述DNMSI2C 是一款专为 DNMS Teensy 声音传感器模块设计的轻量级 IC 驱动库,面向嵌入式音频监测场景提供标准化、低开销的声压级(SPL)数据采集能力。该库不依赖浮点运算或动态内存分配,完全适配资源受限的微控制器平台&am…...

为什么99%的Python团队还没用上AOT?2026年官方方案的3大硬伤与2个绕过技巧(含patch diff与CI集成脚本)

第一章:Python 原生 AOT 编译方案 2026 概览与演进脉络Python 长期以来以解释执行和 JIT 辅助(如 PyPy)为主流运行范式,而原生 Ahead-of-Time(AOT)编译在 2026 年迎来实质性突破:CPython 官方正…...

Ryzen SDT调试工具:解锁AMD处理器隐藏性能的终极指南

Ryzen SDT调试工具:解锁AMD处理器隐藏性能的终极指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://git…...

Java应用等保三级合规改造:3天完成代码层、配置层、运维层全栈优化(附Checklist)

第一章:Java应用等保三级合规改造全景图等保三级是国家网络安全等级保护制度中面向重要信息系统的核心要求,对Java应用而言,合规改造不是单一技术点的修补,而是一套覆盖开发、运行、运维全生命周期的安全治理工程。其核心目标在于…...

2026顶空气体分析仪TOP5|权威评测与选购指南

顶空气体分析仪,又叫顶空残氧仪,主要用于测量封闭容器中顶部空间氧气与二氧化碳的浓度。随着市场需求越来越大,市面上品牌五花八门,新手选购易踩雷、难抉择。本次榜单严格遵循客观数据真实口碑原则,综合公司背景、技术…...

GTE-Base-ZH一键部署教程:3步在Ubuntu上搭建语义检索服务

GTE-Base-ZH一键部署教程:3步在Ubuntu上搭建语义检索服务 想给自己的应用加个智能搜索功能,但一看到复杂的模型部署就头疼?别担心,今天咱们就来聊聊怎么用最简单的方法,在Ubuntu系统上把GTE-Base-ZH这个强大的中文语义…...

OpenClaw飞书机器人实战:Qwen3-32B-Chat私有镜像接入

OpenClaw飞书机器人实战:Qwen3-32B-Chat私有镜像接入 1. 为什么选择OpenClaw飞书本地大模型? 去年我接手了一个小团队的效率工具改造项目,核心需求是"在不泄露内部数据的前提下,实现自动化日报生成和文件归档"。尝试过…...

Electron 14+ 开发必看:WebContentsView 实战指南(含与 BrowserView 对比)

Electron 14 开发实战:WebContentsView 深度解析与性能优化 如果你正在使用 Electron 14 开发跨平台桌面应用,那么 WebContentsView 绝对是你需要重点掌握的核心组件。作为 Electron 团队在 14 版本引入的全新视图系统,WebContentsView 不仅解…...

MusePublic助力Java开发者:SpringBoot集成指南

MusePublic助力Java开发者:SpringBoot集成指南 1. 为什么Java团队需要MusePublic能力 最近帮一家电商公司做推荐系统升级时,技术负责人跟我聊起一个现实问题:他们用传统协同过滤算法生成的商品推荐列表,点击率已经连续三个季度停…...