【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流
导读
在文件I/O这一节的知识里,对文件的操作主要分为两大类:
☑️针对文件系统进行的操作
☑️针对文件内容进行的操作
上文已经讲了针对文件系统即File类的操作,这篇文章里博主就来带了解针对文件内容的操作,即输入输出流(Reader,Writer,InputStream,OutputStream)四种流相关知识📖
前置知识
1、流的分类
文件I/O中的流分为字节流和字符流
字符流:以字符为单位,每次读写的最小单位是字符;对应文本文件。包括Reader,Writer两个类
字节流:以字节为单位,每次读写的最小单位是字节;对应二进制文件。包括InputStream,OutputStream两个类
流的关系分类如下图

注意,字符和字节的关系如下
一个字符可能是对应多个字节
GBK,一个中文字符 ->两个字节
UTF8,一个中文字符 ->三个字节
2、输入输出的定义
计算机中的输入输出发生在CPU和硬盘之间,而我们所说的输入输出是以CPU为视角,即
· 把数据从CPU保存到硬盘上,是输出/写(Input/Read)
· 把内容从硬盘取到CPU里,是输入/读(Output/Write)
下图可以形象地表示输入输出的定义

四种流的使用
1、Reader
(1)Reader类
先创建一个Reader
Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt");
(2)Reader类中的方法
Reader最常用的就是read方法,read方法分为下面几种

| 方法名 | 说明 |
| read(char[] cbuf) | 传入数组参数,读取数组长度的字符存放在数组中 |
| read () | 读一个字符 |
| read(CharBuffer target) | 传入CharBuffer对象 |
| read(char[] cbuf,int off, int length) | 传入数组参数,从字符串off位置开始读,读取length长度的字符存放在数组中 |
(3)代码实例
其中最常用的是read(char[] cbuf)方法,返回参数是读取字符的个数
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;public class demo {public static void main(String[] args){char[] buf = new char[12];try(Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt")) {while (true){int n = reader.read(buf);if(n == -1){break;}System.out.println("n="+n);for (int i = 0; i < n; i++) {System.out.print(buf[i]);}System.out.println();}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}
注意:代码中将Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt放在try()代码块中是隐藏了reader.close()操作,相当于
try {Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt")while (true){int n = reader.read(buf);if(n == -1){break;}System.out.println("n="+n);for (int i = 0; i < n; i++) {System.out.print(buf[i]);}System.out.println();}
} catch (FileNotFoundException e) {throw new RuntimeException(e);
} catch (IOException e) {throw new RuntimeException(e);
}finally{reader.close();
}
读取结果

2、Writer类
(1)Writer中的方法
Writer方法如下

| 方法名 | 说明 |
| write(String str) | 一次写一个字符串 |
| write(char[] cbuf) | 一次写多个字符(字符数组) |
| write(int c) | 一次写一个字符 |
| write(String str, int off, int len) | 带有 offset 和lenoffset指的是从字符串中的第几个字符开始写 |
| write(char[] cbuf, int off, int len) | 带有 offset 和lenoffset 指的是从数组中的第几个字符开始写 |
(2)代码实例
我们最常用的是第一个即write(String str)方法
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class demo3 {public static void main(String[] args) {try(Writer writer = new FileWriter("/Users/liuwenwen/Desktop/test.txt")) {writer.write("驻跸怀千古,开襟望九州。太平词藻盛,长愿纪鸿休。");} catch (IOException e) {throw new RuntimeException(e);}}
}
运行程序后,文本内容被修改了😦

可见我们原来的内容同时也被覆盖。如果不想覆盖原本的内容,怎么办呢?🤔
在创建Writer类时,加一个参数true,表示追加
try(Writer writer = new FileWriter("/Users/liuwenwen/Desktop/test.txt",true))
为了防止由于程序运行太快,内容在缓冲区中没有来得及写到硬盘里,我们加一个flush()方法
writer.flush();
现在整体代码就变成
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class demo3 {public static void main(String[] args) {try(Writer writer = new FileWriter("/Users/liuwenwen/Desktop/test.txt",true)) {writer.write("驻跸怀千古,开襟望九州。太平词藻盛,长愿纪鸿休。");writer.flush();} catch (IOException e) {throw new RuntimeException(e);}}
}
用原来的文本再次运行程序

可以看到,这次是追加,不再是覆盖
3、InputStream类
(1)方法
InputStream类和Reader类里的方法类似,不过将char[]数组变为了byte[]数组,返回值是读取字节的个数

(2)代码实例
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class demo5 {public static void main(String[] args) {try (InputStream inputStream = new FileInputStream("/Users/liuwenwen/Desktop/test.txt")){byte[] buf = new byte[1024];int n = inputStream.read(buf);for (int i = 0; i < n; i++) {System.out.printf("%x ",buf[i]);//采用十六进制打印,更加直观}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}
读取结果

4、OutputStream类
(1)方法
OutputStream类和Writer类里的方法类似,不过将char[]数组变为了byte[]数组

(2)代码实例
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class demo6 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("/Users/liuwenwen/Desktop/test.txt",true)){String s = "驻跸怀千古,开襟望九州。太平词藻盛,长愿纪鸿休。";outputStream.write(s.getBytes());} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}
由于OutputStream类write方法要传入的是byte[]参数,我们直接调用字符串的getBytes()方法,方便书写
最终追加结果

相关文章:
【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流
导读 在文件I/O这一节的知识里,对文件的操作主要分为两大类: ☑️针对文件系统进行的操作 ☑️针对文件内容进行的操作 上文已经讲了针对文件系统即File类的操作,这篇文章里博主就来带了解针对文件内容的操作,即输入输出流&am…...
rocky8.9配置K8S集群kubernetes,centos同理
注意!!! 虚拟机实验环境不要使用’克隆’!!! 唯一标识冲突:K8S集群中的每个节点都需要具有唯一的标识符,例如节点名称、IP地址、MAC地址等。当克隆虚拟机时,这些唯一标识…...
Linux下的文件IO之系统IO
1. 知识点 读入写出,切记以我们程序为中心向文件或者别的什么东西读入写出(输入流输出流) 人话就是 文件向我们程序就是读入 程序向文件或者别的什么就是写出 2. open打开文件 open.c /****************************************************…...
iptables防火墙之SNAT与DNAT
1. SNAT SNAT 应用环境:局域网主机共享单个公网IP地址接入Internet (私有IP不能在Internet中正常路由) SNAT原理:源地址转换,根据指定条件修改数据包的源IP地址,通常被叫做源映射。 数据包从内网发送到公网时,SNAT会把数据包的源IP由私网IP…...
Python与设计模式--命令模式
23种计模式之 前言 (5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、(11)策略模式、责任链模式、命令模式、中介者模…...
uni-app 自带返回方法onBackPress,返回上一级并且刷新页面内容获取最新的数据
onBackPress 返回上一级并且刷新页面内容获取最新的数据 onBackPress 方法是uinapp自带返回键方法,也就是在app和H5返回键 onBackPress() {setTimeout(() > {uni.switchTab({url: /pages/Users/index,})}, 300)return true}, methods: {}在这里 uni.switchTab…...
python用YOLOv8对图片进行分类
用yolov8的模型进行分类 先上效果图 图片资源 模型下载地址 https://github.com/ultralytics/ultralytics 代码 import matplotlib.pyplot as plt from ultralytics import YOLO from PIL import Image import cv2model YOLO(../ultralytics/yolov8n.pt)# print(model…...
Spring中@DependsOn 使用详解
一、注解源码 Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented public interface DependsOn {String[] value() default {}; } 二、基础概念 DependsOn是Spring框架用来指定bean之间依赖关系的注解之一,即可用户类…...
android笔记 SELinux
1.SELinux解错步骤 log信息: 11-20 02:25:12.526 8976 8976 W om.jzzh.setting: type1400 audit(0.0:1316): avc: denied { write } for name"com.jzzh.setting-IWLR9dkz8TWizbNujdTpWw" dev"mmcblk2p15" ino2661 scontextu:r:system_app:s0…...
vue3 keep-alive页面切换报错:parentComponent.ctx.deactivate is not a function
问题: <router-view v-slot"{ Component }"><keep-alive ><component :is"Component" v-if"$route.meta.keepAlive" /></keep-alive><component :is"Component" v-if"!$route.meta.keepA…...
prompt提示
用例生成 # 任务描述 作为一个高级c程序员,需要完成下列功能的gtest测试用例 # 功能描述 给定两个数字型字符串s1和s2,求和,返回值也是字符串 # 接口举例 调用strAdd("123", "132"),输出“255” # 输出要求 - 入参为空串、nu…...
边缘计算网关:智能制造的“智慧大脑”
一、智能制造的崛起 随着科技的飞速发展,智能制造已经成为了制造业的新趋势。智能制造不仅能够提高生产效率,降低生产成本,还能够实现个性化定制,满足消费者多样化的需求。然而,智能制造的实现离不开大量的数据处理和分…...
HNCTF2022Week1 Reverse WP
文章目录 [HNCTF 2022 Week1]超级签到[HNCTF 2022 Week1]贝斯是什么乐器啊?[HNCTF 2022 Week1]X0r[HNCTF 2022 Week1]你知道什么是Py嘛?[HNCTF 2022 Week1]CrackMe[HNCTF 2022 Week1]给阿姨倒一杯Jvav[HNCTF 2022 Week1]Little EndianNSSCTF{Littl3_Endi…...
基于Python的面向对象分类实例Ⅱ
接上一部分继续介绍~ 一、地类矢量转栅格 这一步是为了能让地类值和影像的对象落在同一区域,从而将影像中的分割对象同化为实际地物类别。 train_fn r".\train_data1.shp" train_ds ogr.Open(train_fn) lyr train_ds.GetLayer() driver gdal.GetDrive…...
android手机莫名其妙卸载重装有残留数据
参考文档: https://developer.android.com/guide/topics/data/autobackup?hlzh-cn https://developer.android.com/about/versions/12/backup-restore#xml-changes https://stackoverflow.com/questions/70365809/how-to-specify-to-not-allow-any-data-backup-wit…...
【YOLOv5入门】目标检测
【大家好,我是爱干饭的猿,本文重点介绍YOLOv5入门-目标检测的任务、性能指标、yolo算法基本思想、yolov5网络架构图。 后续会继续分享其他重要知识点总结,如果喜欢这篇文章,点个赞👍,关注一下吧】 上一篇…...
可验证随机函数(VRF)
文章目录 一、背景以及场景共识发展第一代 POW “以力取胜”第二代 POS/DPOS “民主投票”第三代 VRF “运气抽签” 二、可验证随机函数(VRF)快速开始1. VRF是什么?2. MD5 hash函数和VRF(Verifiable Random Function)区别3. VRF-…...
Node.js与npm的准备与操作
1.下载 Node.js官网:Node.jsNode.js is a JavaScript runtime built on Chromes V8 JavaScript engine.https://nodejs.org/en 打开后的界面如下: LTS(Long Term Support):长期支持版,稳定版 Current&am…...
ui设计师简历自我评价的范文(合集)
ui设计师简历自我评价的范文篇一 本人毕业于艺术设计专业,具有较高的艺术素养,平时注重设计理论知识的积累,并将理论应用到作品中。了解当下设计的流行趋势,设计注重细节、重视用户体验,对色彩搭配有着浓厚的兴趣&…...
sqli-labs靶场详解(less32-less37)
宽字节注入 原理在下方 目录 less-32 less-33 less-34 less-35 less-36 less-37 less-32 正常页面 ?id1 下面有提示 获取到了Hint: The Query String you input is escaped as : 1\ ?id1 看来是把参数中的非法字符就加上了转义 从而在数据库中只能把单引号当成普通的字…...
我设计了一套自己的多agent协作体系:星核协作体系
我设计了一套自己的多agent协作体系:星核协作体系 我自己的三省六部制我希望有一个能力强大的个人助手——这是我做星核最初的出发点。 当一个任务需要同时搞定架构设计、内容创作、代码实现、还要确保安全合规,指望一个Agent从头做到尾,基本…...
A*、遗传、蚁群优化和元胞自动机四种经典算法实现四种场景下六边形网格路径规划,Python代码
基于六边形网格的路径规划算法摘要路径规划是机器人导航、智能交通和游戏AI等领域的核心问题。本期推文基于六边形网格结构,系统地对比了四种经典路径规划算法:A*算法、遗传算法、蚁群优化算法和元胞自动机算法。通过设计四组不同规模和复杂度的测试场景…...
实战演练:基于快马平台快速构建一个电商客服对话agent系统
今天想和大家分享一个实战项目:如何在InsCode(快马)平台快速搭建一个电商客服对话agent系统。这个项目特别适合想体验AI对话系统开发的朋友,整个过程不需要复杂的配置,半小时就能看到效果。 需求分析 电商客服系统最核心的功能就是处理用户的…...
3个突破让你自由掌控数字阅读:fanqienovel-downloader全攻略
3个突破让你自由掌控数字阅读:fanqienovel-downloader全攻略 【免费下载链接】fanqienovel-downloader 下载番茄小说 项目地址: https://gitcode.com/gh_mirrors/fa/fanqienovel-downloader 如何确保你钟爱的网络小说永不消失? 当你在通勤途中打…...
告别复杂配置!intv_ai_mk11一键部署,小白也能轻松体验AI写作
告别复杂配置!intv_ai_mk11一键部署,小白也能轻松体验AI写作 1. 为什么选择intv_ai_mk11 在AI技术快速发展的今天,文本生成模型已经成为内容创作、客服问答、文案撰写等多个领域的得力助手。然而,对于大多数非技术背景的用户来说…...
如何通过智能提取技术实现B站视频内容转化?解密高效提取的技术民主化方案
如何通过智能提取技术实现B站视频内容转化?解密高效提取的技术民主化方案 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 在信息爆炸的数字时代&a…...
Qwen3-14B制造业工艺文档生成:设备操作SOP自动编写与版本管理
Qwen3-14B制造业工艺文档生成:设备操作SOP自动编写与版本管理 1. 引言:制造业文档自动化的迫切需求 在制造业生产现场,设备操作标准作业程序(SOP)是确保产品质量和生产安全的关键文档。传统SOP编写方式面临三大痛点: 人力成本高…...
OpenClaw技能共享:将Qwen2.5-VL-7B定制插件发布到ClawHub
OpenClaw技能共享:将Qwen2.5-VL-7B定制插件发布到ClawHub 1. 为什么需要共享OpenClaw技能 去年我开发了一个基于Qwen2.5-VL-7B的图片分析插件,能够自动识别截图中的UI元素并生成操作指令。当我发现这个插件在团队内部被反复复制粘贴使用时,…...
用STC89C51+ESP8266-01做个宿舍环境监测器,再用App Inventor2做个手机App(保姆级避坑指南)
宿舍环境监测器实战:STC89C51ESP8266与App Inventor 2避坑指南 凌晨三点,室友的鼾声和窗外施工噪音让你辗转难眠。更糟的是,你发现喉咙干涩、头昏脑胀——这间不到20平米的宿舍里,二氧化碳浓度早已超标。作为电子爱好者࿰…...
忍者像素绘卷:天界画坊Python入门实战:零基础AI绘画环境搭建
忍者像素绘卷:天界画坊Python入门实战:零基础AI绘画环境搭建 1. 前言:为什么选择像素风格AI绘画 像素艺术近年来在独立游戏、数字艺术领域持续升温。这种复古又充满创意的表现形式,让许多开发者跃跃欲试。但传统像素画需要扎实的…...
