招聘面试季--一文顿悟,Java中字节流和字符流的区别及使用场景上的差异
一、核心区别
| 特性 | 字节流 | 字符流 |
|---|---|---|
| 数据单位 | 以字节(8-bit)为单位处理数据(如0xA1) | 以字符(16-bit Unicode)为单位处理数据(如'A', '你') |
| 基类 | InputStream / OutputStream | Reader / Writer |
| 底层依赖 | 直接操作原始字节,不涉及编码转换 | 基于字节流实现,自动处理字符编码(如UTF-8、GBK) |
| 典型实现类 | FileInputStream / FileOutputStream | FileReader / FileWriter |
二、使用场景差异
1. 字节流的适用场景
字节流直接操作原始字节,适合处理二进制数据或不涉及字符编码的数据:
- 二进制文件:如图片(
jpg、png)、音频(mp3)、视频(mp4)等。 - 网络传输:通过字节流传输原始数据(如Socket通信)。
- 加密/压缩数据:处理需要保留字节完整性的场景。
示例:复制图片文件(二进制数据)
try (InputStream in = new FileInputStream("input.jpg");OutputStream out = new FileOutputStream("output.jpg")) {byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {out.write(buffer, 0, bytesRead);}
2. 字符流的适用场景
字符流自动处理字符编码,适合处理文本数据:
- 文本文件:如
txt、csv、xml、json等。 - 需要字符编码的场景:如读取UTF-8、GBK等编码的文本。
- 逐行处理文本:如
BufferedReader.readLine()。
示例:读取UTF-8编码的文本文件
try (Reader reader = new InputStreamReader(new FileInputStream("input.txt"), StandardCharsets.UTF_8);BufferedReader br = new BufferedReader(reader)) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}
}
三、关键注意事项
-
字符流的编码问题:
FileReader和FileWriter默认使用平台编码(如Windows的GBK),可能导致乱码。推荐显式指定编码:// 使用InputStreamReader指定UTF-8编码 Reader reader = new InputStreamReader(new FileInputStream("input.txt"), StandardCharsets.UTF_8);
-
避免混用字节流和字符流:
- 用字符流处理二进制文件(如图片)会导致数据损坏(字符流会尝试将字节解码为字符,可能破坏原始数据)。
-
性能优化:
- 无论字节流还是字符流,都应配合缓冲类(如
BufferedInputStream、BufferedReader)提升性能。
- 无论字节流还是字符流,都应配合缓冲类(如
四、先导结论的总结
| 场景 | 应选流类型 | 原因 |
|---|---|---|
| 图片、视频、加密数据 | 字节流 | 保留原始字节,避免编码转换破坏数据 |
| 中文文本文件 | 字符流 | 自动处理编码,确保正确解析多字节字符 |
| 网络传输原始数据 | 字节流 | 直接操作字节,无需字符编码逻辑 |
选择正确的流类型可以避免数据损坏和乱码问题,同时提高代码可读性和性能。
另一个思考,既然字符流底层也是用字节流实现,为啥我还需要一个字符流,能给我带来啥好处
字符流虽然底层依赖字节流实现,但它的抽象层解决了几个字节流无法直接处理的 核心痛点,尤其是在处理文本数据时。以下是字符流存在的核心价值:
一、字符流的核心优势
1. 自动处理字符编码(核心价值)
字节流操作的是原始字节(byte),而字符流操作的是字符(char)。字符流在底层通过 InputStreamReader / OutputStreamWriter 自动完成字节与字符的编解码,避免了手动处理编码的复杂性。
示例:读取UTF-8文本文件
- 用字节流实现(需手动处理编码)
try (InputStream in = new FileInputStream("text.txt")) {byte[] bytes = in.readAllBytes();String text = new String(bytes, StandardCharsets.UTF_8); // 需显式指定编码System.out.println(text);
}
- 用字符流实现(自动处理编码):
try (Reader reader = new InputStreamReader(new FileInputStream("text.txt"), StandardCharsets.UTF_8)) {char[] buffer = new char[1024];int charsRead;while ((charsRead = reader.read(buffer)) != -1) {System.out.print(new String(buffer, 0, charsRead));}
}
优势:字符流直接将字节转换为字符,避免开发者手动处理编码,减少代码冗余和错误。
2. 处理多字节字符(如中文)
字符流能正确解析多字节编码(如UTF-8中的中文字符),而字节流可能因拆分字节导致乱码。
示例:UTF-8编码的中文字符“你好”
- UTF-8编码为6字节:
0xE4 0xBD 0xA0 0xE5 0xA5 0xBD。 - 字节流的风险:
byte[] buffer = new byte; // 假设缓冲区大小为3字节
in.read(buffer); // 可能只读到前3字节 0xE4 0xBD 0xA0,对应字符“你”
in.read(buffer); // 再读后3字节 0xE5 0xA5 0xBD,对应字符“好”
// 但如果缓冲区大小是4字节,可能拆分为错误的字节序列,导致乱码!
优势:字符流内部维护编码状态机,确保多字节字符的完整性,避免手动处理字节拆分。
3. 提供更高层次的文本操作API
字符流提供针对文本的便捷方法,而字节流只能操作原始字节:
- 逐行读取:
BufferedReader.readLine()。 - 按字符处理:直接读取字符数组(
char[])。 - 格式化写入:
PrintWriter.printf()。
示例:逐行读取文本文件
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("log.txt"), StandardCharsets.UTF_8))) {String line;while ((line = br.readLine()) != null) { // 直接按行读取System.out.println(line);}
}
优势:无需自行实现换行符(\n、\r\n)识别逻辑,简化代码。
二、为什么不能直接用字节流替代字符流?
虽然可以通过字节流+手动编码实现字符流的功能,但会遇到以下问题:
- 代码冗余:每次都需要调用
new String(bytes, charset)或String.getBytes(charset)。 - 容易出错:手动处理字节拆分、编码兼容性(如UTF-8与GBK混用)。
- 性能损失:频繁的字节-字符转换可能降低效率(字符流内部有优化)。
三、字符流的适用场景总结
| 场景 | 使用字符流的原因 |
|---|---|
读取/写入文本文件(如.txt) | 自动处理编码,避免乱码 |
| 处理用户输入(控制台、表单) | 直接按字符处理,无需关心底层字节 |
| 需要逐行操作文本(如日志解析) | 提供readLine()等高级API |
| 跨平台文本处理 | 显式指定编码(如UTF-8),确保环境一致性 |
四、关键结论
字符流的本质是 “字节流 + 编码抽象层”,它通过封装以下细节简化开发:
- 字符与字节的自动转换(编码/解码)。
- 多字节字符的完整性处理(如UTF-8的3字节字符)。
- 提供面向文本的高级API(如按行读取)。
使用原则:
- 处理文本数据时,优先使用字符流(指定明确编码)。
- 处理二进制数据时,必须使用字节流。
🎉🎊🥳👏💃🕺✨🎆🎇💥💫🌟🔥💪💯
更多Java面试的技术和方法论文章,点击这里,可以前往“面试谈”专栏探索更多
🎉🎊🥳👏💃🕺✨🎆🎇💥💫🌟🔥💪💯
相关文章:
招聘面试季--一文顿悟,Java中字节流和字符流的区别及使用场景上的差异
一、核心区别 特性字节流字符流数据单位以字节(8-bit)为单位处理数据(如0xA1)以字符(16-bit Unicode)为单位处理数据(如A, 你)基类InputStream / OutputSt…...
使用【docker】+【shell】脚本半自动化部署微服务项目
一.前言 以下是一个基于 Docker Shell脚本 的半自动化部署方案,包含镜像构建、容器管理、网络配置和日志监控等核心功能,适用于大多数Web应用或微服务项目。 二.目录结构 三.脚本代码实现 1.Shell脚本实现 (deploy.sh) #!/bin/bash# 设置颜…...
uni-app——计时器和界面交互API
API 基本概要 概念说明 API(应用程序接口)是预先定义的方法集合,用于实现特定功能。在 uni-app 中,通过全局对象 uni 调用 API,例如 uni.getSystemInfoSync 获取设备信息。 API 分类与调用规则 事件监听型 以 on 开…...
使用 GitHub 可重用工作流和 GitHub Actions 简化 DevOps
在当今的 DevOps 环境中,自动化是开发团队能够更快地交付功能并维护高质量代码库的关键。这就是像 GitHub Actions 这样的工具变得不可或缺的地方,因为它能够直接在存储库中自动化、自定义和执行 GitHub 工作流程。 当然,随着项目的规模和存…...
深入理解MySQL日志机制
目录 1. MySQL日志概述 2. 错误日志(Error Log) 2.1 错误日志的作用 2.2 错误日志的配置 2.3 查看错误日志 3. 二进制日志(Binary Log) 3.1 二进制日志的作用 3.2 二进制日志的配置 3.3 查看二进制日志 3.4 二进制日志的…...
Sql Server 索引性能优化 分析以及分表
定位需优化语句 根据工具 skywking 或者开启慢查询日志 找到 慢sql 的语句根据 执行过程 来 判断 慢的原因 row filter 指标 看查了多少数据 比例多少 type 看下是单表 还是 join联表 比如 执行步骤多 没索引 优化方向 减少执行次数索引 没索引考虑加索引 加索引 尽量选择 i…...
vue使用element-ui自定义样式思路分享【实操】
前言 在使用第三方组件时,有时候组件提供的默认样式不满足我们的实际需求,需要对默认样式进行调整,这就需要用到样式穿透。本篇文章以vue3使用element-ui的Tabs组件,对Tabs组件的添加按钮样式进行客制化为例。 确定需要修改的组…...
2020年全国职业院校技能大赛改革试点赛高职组“云计算”竞赛赛卷第二场次题目:容器云平台部署与运维
2020年全国职业院校技能大赛改革试点赛高职组 “云计算”竞赛赛卷 第二场次题目:容器云平台部署与运维 说明:本任务提供有2台服务器master和node,都安装了centos7.5操作系统,在/opt/centos目录下有CentOS-7-x86_64-DVD-1804系统光盘文件所有文件,在/opt/containerk8s目…...
PowerBI 条形图,解决数据标签在条形内部看不清的问题
比如下面的条形图: 最上面两行,数据标签显示在了条形内部,哪怕设置了值为黑色 字体也会自动切换为白色,如果设计要求条形的颜色是浅色,就会导致数据看不清晰。 解决方法一: 将数据标签位置设置为端外 效果…...
下载与快速上手 NVM:Node.js 版本管理工具
一、准备工作:卸载旧版 Node.js 重要提示:在安装 NVM 前,请先彻底删除已安装的 Node.js,避免路径冲突: 检查安装路径 bash where node常见路径: C:\Program Files\nodejs\C:\Users\用户名\AppData\Local\n…...
网络防火墙(Firewall)、Web防火墙(WAF)、入侵检测系统(IDS)、入侵防御系统(IPS)对比总结
目录 一、Firewall、WAF、IDS、IPS四种设备简介 二、Firewall、WAF、IDS、IPS四种设备的角色定位 三、防火墙(Firewall)与入侵检测系统(IPS)的区别 四、入侵检测系统(IDS)与入侵防御系统(IP…...
Unity | 游戏数据配置
目录 一、ScriptableObject 1.创建ScriptableObject 2.创建asset资源 3.asset资源的读取与保存 二、Excel转JSON 1.Excel格式 2.导表工具 (1)处理A格式Excel (2)处理B格式Excel 三、解析Json文件 1.读取test.json文件 四、相关插件 在游戏开发中,策划…...
IT工具 | node.js 进程管理工具 PM2 大升级!支持 Bun.js
P(rocess)M(anager)2 是一个 node.js 下的进程管理器,内置负载均衡,支持应用自动重启,常用于生产环境运行 node.js 应用,非常好用👍 🌼概述 2025-03-15日,PM2发布最新版本v6.0.5,这…...
VulnHub-Web-Machine-N7通关攻略
一、信息收集 第一步:确定靶机IP为192.168.0.107 第二步:扫描后台及开放端口 第三步:进行敏感目录及文件扫描 http://192.168.0.107/index.html (CODE:200|SIZE:1620) http://192.168.0.107/server-status (CODE:403|SIZ…...
发现一个好用的Vue.js内置组件
目录 一、这个好用的内置组件是什么? 二、这个组件的主要功能 三、怎么使用? 四、使用注意事项 五、我的使用场景 一、这个好用的内置组件是什么? 今天在优化我的平台应用时,发现一个好用的组件标签--<keep-alive>。 …...
论华为 Pura X 折叠屏性能检测
在科技浪潮中,折叠屏手机以其创新形态掀起市场热潮。华为 Pura X 作为华为最新折叠手机,承载前沿科技与精湛工艺,成为行业焦点。它融合先进折叠屏技术与优质材质,致力于打破传统手机使用边界,为用户开启全新体验。但产…...
生成PDF文件:从html2canvas和jsPdf渲染到Puppeteer矢量图
刚刚实现而已:第一次明白,双击或file:///打开html文件,居然和从localhost:3000打开同一个html文件有本质的区别。 字体居然还能以Base64代码嵌入到网页,只是太大太笨。 需要安装node.js,npm安装更多依赖:…...
在 Elasticsearch 中探索基于 NVIDIA 的 GPU 加速向量搜索
作者:来自 Elastic Chris Hegarty 及 Hemant Malik 由 NVIDIA cuVS 提供支持,此次合作旨在为开发者在 Elasticsearch 中的向量搜索提供 GPU 加速。 在 Elastic Engineering 组织内,我们一直致力于优化向量数据库的性能。我们的使命是让 Lucen…...
Junit在测试过程中的使用方式,具体使用在项目测试中的重点说明
JUnit 是一个广泛使用的 Java 单元测试框架,主要用于编写和运行可重复的测试。以下是 JUnit 在项目测试中的使用方式和重点说明: 1. 基本使用 场景:测试一个简单的 Java 类。 示例: import org.junit.Test; import static org.junit.Assert.*;public class CalculatorTe…...
关于CNN,RNN,GAN,GNN,DQN,Transformer,LSTM,DBN你了解多少
以下是神经网络中常见的几种模型的简要介绍: 1. CNN (Convolutional Neural Network, 卷积神经网络) 用途: 主要用于图像处理和计算机视觉任务。特点: 通过卷积核提取局部特征,具有平移不变性,能够有效处理高维数据(如图像…...
asp.net 4.5在医院自助系统中使用DeepSeek帮助医生分析患者报告
环境: asp.net 4.5Visual Studio 2015本地已经部署deepseek-r1:1.5b 涉及技术 ASP.NET MVC框架用于构建Web应用程序。使用HttpWebRequest和HttpWebResponse进行HTTP请求和响应处理。JSON序列化和反序列化用于构造和解析数据。SSE(服务器发送事件…...
HeyGem.ai 全离线数字人生成引擎加入 GitCode:开启本地化 AIGC 创作新时代
在人工智能技术飞速演进的时代,数据隐私与创作自由正成为全球开发者关注的焦点。硅基智能旗下开源项目 HeyGem.ai 近日正式加入 GitCode,以全球首个全离线数字人生成引擎的颠覆性技术,重新定义人工智能生成内容(AIGC)的…...
密码协议与网络安全——引言
三个基本概念 计算机安全(Computer Security):对于一个自动化的信息系统,采取保护措施确保信息系统资源(包括硬件、软件、固件、信息、数据和通信)的保密性、完整性和可用性。 网络安全(Netwo…...
springboot实现调用百度ocr实现身份识别+二要素校验
一、技术选型 OCR服务:推荐使用百度AI 二、实现 1.注册一个服务 百度智能云控制台https://console.bce.baidu.com/ai-engine/ocr/overview/index?_1742309417611 填写完之后可以获取到app-id、apiKey、SecretKey这三个后面文件配置会用到 2、导入依赖 <!-- …...
MATLAB 控制系统设计与仿真 - 28
MATLAB状态空间控制系统分析 - 极点配置 就受控系统的控制律的设计而言,由状态反馈极点配置和输出反馈极点配置。 状态反馈极点配置问题就是:通过状态反馈矩阵K的选取,使闭环系统的极点,即(A-BK)的特征值恰好处于所希望的一组给定闭环极点的位置。 另外,线性定常系统可…...
JetsonNano —— 4、Windows下对JetsonNano板卡烧录刷机Ubuntu20.04版本(官方教程)
介绍 NVIDIA Jetson Nano™ 开发者套件是一款面向创客、学习者和开发人员的小型 AI 计算机。按照这个简短的指南,你就可以开始构建实用的 AI 应用程序、酷炫的 AI 机器人等了。 烧录刷机 1、下载 Jetson Nano开发者套件SD卡映像 解压出.img文件并记下它在计算机上的…...
加速还是安全?CDN与群联云防护的本质差异与适用场景
一、核心功能定位对比 维度传统CDN群联云防护核心目标内容加速(降低延迟、提升访问速度)安全防护(抵御DDoS/CC攻击、隐藏源站)技术重心缓存优化、边缘节点分发流量清洗、AI行为分析、加密隧道主要能力静态资源缓存、负载均衡攻击…...
简单理解机器学习中top_k、top_p、temperature三个参数的作用
在机器学习中,top_k、top_p 和 temperature 是用于控制生成模型(如语言模型)输出质量的参数,尤其在文本生成任务中常见。然而,网上文章很多很全,但大多晦涩难懂,今天我们来用最简单的语言谈谈它…...
Java面试黄金宝典6
1. 什么是 CAS 原理: CAS (Compare-And-Swap)是一种硬件级别的原子操作指令,在 Java 并发编程中常被用于实现无锁算法。其核心逻辑是:在进行数据更新时,会先将内存位置 V 的值与预期原值 A 进行比较&#x…...
【深度学习新浪潮】AI ISP技术与手机厂商演进历史
本文是关于AI ISP(人工智能图像信号处理器)的技术解析、与传统ISP(图像信号处理器)的区别、近三年研究进展,以及各大手机厂商在该领域演进历史的详细报告。本报告综合多个权威来源的信息,力求全面、深入地呈现相关技术发展脉络与行业动态。 第一部分:AI ISP的定义及与传…...
