JAVA-编程基础-11-04-java IO 字符流
Lison <dreamlison@163.com>, v1.0.0, 2023.05.07
JAVA-编程基础-11-04-java IO 字符流
文章目录
- JAVA-编程基础-11-04-java IO 字符流
- 字符流Reader 和 Writer
- 字符输入流(Reader)
- **FileReader构造方法**
- **FileReader读取字符数据**
- 字符输出流(Writer)
- FileWriter 构造方法
- FileWriter写入数据
字符流Reader 和 Writer
字符流 Reader 和 Writer 的故事要从它们的类关系图开始,来看图。

字符流是一种用于读取和写入字符数据的输入输出流。与字节流不同,字符流以字符为单位读取和写入数据,而不是以字节为单位。常用来处理文本信息。
如果用字节流直接读取中文,可能会遇到乱码问题,见下例:
//FileInputStream为操作文件的字符输入流
FileInputStream inputStream = new FileInputStream("files/a.txt");//内容为“Lison 勤学苦练 !!”int len;
while ((len=inputStream.read())!=-1){System.out.print((char)len);
}
运行结果:
运行结果:Lison 勤å¦è‹¦ç»

之所以出现乱码是因为在字节流中,一个字符通常由多个字节组成,而不同的字符编码使用的字节数不同。如果我们使用了错误的字符编码,或者在读取和写入数据时没有正确处理字符编码的转换,就会导致读取出来的中文字符出现乱码。
例如,当我们使用默认的字符编码(见上例)读取一个包含中文字符的文本文件时,就会出现乱码。因为默认的字符编码通常是 ASCII 编码,它只能表示英文字符,而不能正确地解析中文字符。
那使用字节流该如何正确地读出中文呢?见下例。
//FileInputStream为操作文件的字符输入流//内容为“Lison 勤学苦练 !!”try (FileInputStream inputStream = new FileInputStream("files/a.txt");){byte[] bytes = new byte[1024];int len;while ((len = inputStream.read(bytes)) != -1) {System.out.print(new String(bytes, 0, len));}} catch (Exception e) {e.printStackTrace();}
运行结果: Lison 勤学苦练
为什么这种方式就可以呢?
因为我们拿 String 类进行了解码,查看new String(byte bytes[], int offset, int length)的源码就可以发现,该构造方法有解码功能
public String(byte bytes[], int offset, int length) {checkBounds(bytes, offset, length);this.value = StringCoding.decode(bytes, offset, length);}
继续追看 StringCoding.decode() 方法调用的 defaultCharset() 方法,会发现默认编码是UTF-8,代码如下
static char[] decode(byte[] ba, int off, int len) {String csn = Charset.defaultCharset().name();try {// use charset name decode() variant which provides caching.return decode(csn, ba, off, len);} catch (UnsupportedEncodingException x) {warnUnsupportedCharset(csn);}}
public static Charset defaultCharset() {if (defaultCharset == null) {synchronized (Charset.class) {String csn = AccessController.doPrivileged(new GetPropertyAction("file.encoding"));Charset cs = lookup(csn);if (cs != null)defaultCharset = cs;elsedefaultCharset = forName("UTF-8");}}return defaultCharset;}
在 Java 中,常用的字符编码有 ASCII、ISO-8859-1、UTF-8、UTF-16 等。其中,ASCII 和 ISO-8859-1 只能表示部分字符,而 UTF-8 和 UTF-16 可以表示所有的 Unicode 字符,包括中文字符。
当我们使用 new String(byte bytes[], int offset, int length) 将字节流转换为字符串时,Java 会根据 UTF-8 的规则将每 3 个字节解码为一个中文字符,从而正确地解码出中文。
尽管字节流也有办法解决乱码问题,但不够直接,于是就有了字符流,专门用于处理文本文件(音频、图片、视频等为非文本文件)。
从另一角度来说:字符流 = 字节流 + 编码表
字符输入流(Reader)
java.io.Reader是字符输入流的超类(父类),它定义了字符输入流的一些共性方法:
- 1、
close():关闭此流并释放与此流相关的系统资源。 - 2、
read():从输入流读取一个字符。 - 3、
read(char[] cbuf):从输入流中读取一些字符,并将它们存储到字符数组cbuf中
FileReader 是 Reader 的子类,用于从文件中读取字符数据。它的主要特点如下:
- 可以通过构造方法指定要读取的文件路径。
- 每次可以读取一个或多个字符。
- 可以读取 Unicode 字符集中的字符,通过指定字符编码来实现字符集的转换。
FileReader构造方法
- 1、
FileReader(File file):创建一个新的 FileReader,参数为File对象。 - 2、
FileReader(String fileName):创建一个新的 FileReader,参数为文件名。
代码示例如下:
// 使用File对象创建流对象
File file = new File("files/a.txt");
FileReader fr = new FileReader(file);// 使用文件名称创建流对象
FileReader fr = new FileReader("files/b.txt");
FileReader读取字符数据
①、读取字符:read方法,每次可以读取一个字符,返回读取的字符(转为 int 类型),当读取到文件末尾时,返回-1。代码示例如下:
// 使用文件名称创建流对象
FileReader fr = new FileReader("files/abc.txt");
// 定义变量,保存数据
int b;
// 循环读取
while ((b = fr.read())!=-1) {System.out.println((char)b);
}
// 关闭资源
fr.close();
②、读取指定长度的字符:read(char[] cbuf, int off, int len),并将其存储到字符数组中。其中,cbuf 表示存储读取结果的字符数组,off 表示存储结果的起始位置,len 表示要读取的字符数。代码示例如下:
File textFile = new File("files/abc.txt");// 给一个 FileReader 的示例// try-with-resources FileReadertry(FileReader reader = new FileReader(textFile);) {// read(char[] cbuf)char[] buffer = new char[1024];int len;while ((len = reader.read(buffer, 0, buffer.length)) != -1) {System.out.print(new String(buffer, 0, len));}}catch (Exception e){}
使用 FileReader 从文件中读取字符数据,并将其存储到一个大小为 1024 的字符数组中。每次读取 len 个字符,然后使用 String 构造方法将其转换为字符串并输出。
FileReader 实现了 AutoCloseable 接口,因此可以使用 try-with-resources语句自动关闭资源,避免了手动关闭资源的繁琐操作。
字符输出流(Writer)
java.io.Writer 是字符输出流类的超类(父类),可以将指定的字符信息写入到目的地,来看它定义的一些共性方法:
- 1、
write(int c)写入单个字符。 - 2、
write(char[] cbuf)写入字符数组。 - 3、
write(char[] cbuf, int off, int len)写入字符数组的一部分,off为开始索引,len为字符个数。 - 4、
write(String str)写入字符串。 - 5、
write(String str, int off, int len)写入字符串的某一部分,off 指定要写入的子串在 str 中的起始位置,len 指定要写入的子串的长度。 - 6、
flush()刷新该流的缓冲。 - 7、
close()关闭此流,但要先刷新它。
java.io.FileWriter 类是 Writer 的子类,用来将字符写入到文件。
FileWriter 构造方法
FileWriter(File file): 创建一个新的 FileWriter,参数为要读取的File对象。FileWriter(String fileName): 创建一个新的 FileWriter,参数为要读取的文件的名称。
// 第一种:使用File对象创建流对象
File file = new File("files/a.txt");
FileWriter fw = new FileWriter(file);// 第二种:使用文件名称创建流对象
FileWriter fw = new FileWriter("files/b.txt");
FileWriter写入数据
①、写入字符:write(int b) 方法,每次可以写出一个字符,代码示例如下:
FileWriter fw = null;
try {fw = new FileWriter("output.txt");fw.write(72); // 写入字符'H'的ASCII码fw.write(101); // 写入字符'e'的ASCII码fw.write(108); // 写入字符'l'的ASCII码fw.write(108); // 写入字符'l'的ASCII码fw.write(111); // 写入字符'o'的ASCII码
} catch (IOException e) {e.printStackTrace();
} finally {try {if (fw != null) {fw.close();}} catch (IOException e) {e.printStackTrace();}
}
在这个示例代码中,首先创建一个 FileWriter 对象 fw,并指定要写入的文件路径 “output.txt”。然后使用 fw.write() 方法将字节写入文件中,这里分别写入字符’H’、‘e’、‘l’、‘l’、'o’的 ASCII 码。最后在 finally 块中关闭 FileWriter 对象,释放资源。
需要注意的是,使用 write(int b) 方法写入的是一个字节,而不是一个字符。如果需要写入字符,可以使用 write(char cbuf[]) 或 write(String str) 方法。
写入字符数组:write(char[] cbuf) 方法,将指定字符数组写入输出流。代码示例如下:
FileWriter fw = null;
try {fw = new FileWriter("output.txt");char[] chars = {'H', 'e', 'l', 'l', 'o'};fw.write(chars); // 将字符数组写入文件
} catch (IOException e) {e.printStackTrace();
} finally {try {if (fw != null) {fw.close();}} catch (IOException e) {e.printStackTrace();}
}
相关文章:
JAVA-编程基础-11-04-java IO 字符流
Lison <dreamlison163.com>, v1.0.0, 2023.05.07 JAVA-编程基础-11-04-java IO 字符流 文章目录 JAVA-编程基础-11-04-java IO 字符流字符流Reader 和 Writer字符输入流(Reader)**FileReader构造方法****FileReader读取字符数据** 字符输出流&am…...
亚马逊云代码AI助手CodeWhisperer使用教程
一、CodeWhisperer 简介 1、CodeWhisperer是一款基于机器学习的通用代码生成器,由Amazon出品,可以给我们提供代码建议。 2、CodeWhisperer 基于各种上下文线索提供建议,包括光标在源代码中的位置、位于光标前面的代码、注释,以及…...
2023全新小程序广告流量主奖励发放系统源码 流量变现系统
2023全新小程序广告流量主奖励发放系统源码 流量变现系统 分享软件,吃瓜视频,或其他资源内容,通过用户付费买会员来变现,用户需要付费,有些人喜欢白嫖,所以会流失一部分用户,所以就写了这个系统…...
最详细STM32,cubeMX外部中断
这篇文章将详细介绍 cubeMX外部中断的配置,实现过程。 文章目录 前言一、外部中断的基础知识。二、cubeMX 配置外部中断三、自动生成的代码解析四、代码实现。总结 前言 实验开发板:STM32F103C8T6。所需软件:keil5 , cubeMX 。实…...
云栖大会?全部免费!!抢先一步看!
2023云栖大会定档10月31日! 点击链接免费预约云栖门票: 2023云栖大会-领票页面 2023 云栖大会将于 10.31-11.2 在杭州云栖小镇举办,深度拥抱大数据AI 核心技术,见证阿里云大数据AI产品年度重磅发布及创新。开放融合的科技展示平…...
Linux常用的调试工具
在开发和调试Linux的过程中,经常会遇到各种各样的问题,如程序崩溃、性能低下、内存泄漏等。这时候,调试就显得尤为重要。调试技巧和工具能够帮助开发人员快速定位问题并快速解决。在本文中,我们将介绍一些常用的Linux调试技巧和工…...
PX4-Autopilot下载与编译
文章目录 1 Git clone 代码2 下载子模块3 编译4 可能遇到的问题参考 1 Git clone 代码 Github Repository 链接:PX4-Autopilot 查看现有版本: 在终端用命令下载,-b表示branch git clone -b v1.14.0 https://github.com/PX4/PX4-Autopilot.…...
关于数据可视化那些事
干巴巴的数据没人看,数据可视化才能直观展现数据要点,提升数据分析、数字化运营决策效率。那关于可视化的实现方式、技巧、工具等,你了解几分?接下来,我们就来聊聊数据可视化那些事。 1、什么是数据可视化?…...
【Java小知识点】类加载器的区别
🎄欢迎来到边境矢梦的csdn博文🎄 🎄本文主要梳理Java类加载器的区别🎄 🌈我是边境矢梦,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下🫰ᾯ…...
分布式微服务技术栈-SpringCloud<Eureka,Ribbon,nacos>
微服务技术栈 一、微服务 介绍了解1 架构结构案例与 springboot 兼容关系拆分案例拆分服务拆分-服务远程调用 2 eureka注册中心Eureka-提供者与消费者Eureka-eureka原理分析Eureka-搭建eureka服务Eureka-服务注册Eureka-服务发现 3 Ribbon组件 负载均衡Ribbon-负载均衡原理Ribb…...
Unity解决:导出AndroidStudio工程 出现如下报错的解决方法
unity2019.4+ androidStudio2023.x+ 问题1: cvc-complex-type.2.4.a: 发现了以元素 base-extension 开头的无效内容。应以 {layoutlib} 之一开头。 解决:第一个Build.gradle更改如下 // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING …...
Mac电脑怎么在Dock窗口预览,Dock窗口预览工具DockView功能介绍
DockView是一款Mac电脑上的软件,它可以增强Dock的功能,让用户更方便地管理和切换应用程序。 DockView的主要功能是在 DockQ,栏上显示每个窗口的缩略图,并提供了一些相关的操作选项。当用户将鼠标悬停在Dock栏上的应用程序图标上时…...
Hadoop3教程(三十):(生产调优篇)纠删码
文章目录 (155)纠删码原理纠删码原理纠删码相关命令纠删码策略解释 (156)纠删码案例实操参考文献 (155)纠删码原理 纠删码原理 默认情况下,一个文件在HDFS里会保留3个副本,以此提高…...
用nodejs爬虫台湾痞客邦相册
情景:是这样的,我想保存一些喜欢的小伙伴的照片,一张张保存太慢了, 所以我写了个js,放在国外服务器爬,国内的自己解决~ 使用方法 1.点相册随便一张, 复制url, 这张开始接下来的图片都会保存 /*** 2023年10月23日 22:58:44* 支持解析痞客邦相册* 只需要复制相册第一张图片的ur…...
物联网_01_物理设备的网络接入
设备的网络接入及物理层使用到的传输协议 现在物理设备有两种接入方式,一种是直接接入另一种是网关接入 直接接入 给物理设备添加NB-IOT通信模组等设备使之具有直接接入网络的能力 网关接入 物理设备在本地组网后通过统一的网关接入到网络(ZigBee无线组网网关).网关是处在本地…...
AD9371 官方例程之 tx_jesd 与 xcvr接口映射
AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 : AD9371 官方例程构建及单音信号收发 AD9371 官方例程 时钟间的关系与生成 : AD9371 官方例程HDL详解之JESD204B TX侧时钟生成(一) AD9371 官方例程 时钟间的关系与生成 &…...
UserWarning: CUDA initialization: CUDA unknown error
CUDA在suspend之后不可用问题 问题描述 一觉醒来,电脑cuda不可用 /home/你的电脑/pytorch/lib/python3.8/site-packages/torch/cuda/__init__.py:107: UserWarning: CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up enviro…...
C算法:使用选择排序实现从(大到小/从小到大)排序数组,且元素交换不可使用第三变量。
需求: 使用选择排序实现从(大到小/从小到大)排序,且元素交换不可使用第三变量 (异或交换法) 代码实现: #include <stdio.h> void maopao(int* array,int len,int(*swap)(int a,int b)) {int i,j;for(i0;i<len-1;i){for(ji1;j<…...
用mysql客户端操作时,一直提示 Lost connection to MySQL server during query
问题:ERROR 2013 (HY000): Lost connection to MySQL server during query :查询期间失去与 MySQL 服务器的连接 原因:如果客户端如果太长时间没动静,连接器就会自动将连接断开, 这个时间是由参数wait_timeout控制的,…...
KubeSphere一键安装部署K8S集群(单master节点)-亲测过
1. 基础环境优化 hostnamectl set-hostname master1 && bash hostnamectl set-hostname node1 && bash hostnamectl set-hostname node2 && bashcat >> /etc/hosts << EOF 192.168.0.34 master1 192.168.0.45 node1 192.168.0.209…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
