[Java EE] 文件IO (二):文件内容读写-----数据流

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:🍕 Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀Java EE(94平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

    • 2.2 数据流-----文件内容读写
      • 2.2.1 字节流
        • 2.2.1.1 InputStream概述
        • 2.2.1.2 FileInputStream概述
        • 2.2.1.3 利用Scanner进行字符读取
        • 2.2.1.4 OutputStream概述
        • 2.2.1.5 FileOutputStream概述
      • 2.2.2 字符流
        • 2.2.2.1 Reader
        • 2.2.2.2 Writer

2.2 数据流-----文件内容读写

文件内容读写的操作中常见的包含以下操作:读文件,写文件,打开文件,关闭文件.
Java中通过"流"这样的一组类进行上述的文件操作.
Java中常见的流分为一下两类:字节流和字符流

  • 字节流:以字节为单位进行读写,包括以下两个类,InputStream和OutputStream.
  • 字符流:以字符为单位进行读写,包括以下两个类,Reader和Writer.
    字节流和字符流后面的用法基本上一样,核心操作就是read读,write写.close关闭.

举例说明:水流
在这里插入图片描述
接水和放水的方式有好几种,可以一次性全部放(取)完,也可以分为多次放(取),文件的读写操作也是同样的道理.

文件的读写可以一次性读取完全部的内容,也可以规定一次性读取的字节数.

2.2.1 字节流

字节流这里读取的文件可以是二进制文件,也可以是文本文件

2.2.1.1 InputStream概述

方法:

修饰符及返回值类型⽅法签名说明
intread()读取⼀个字节的数据,返回-1代表已经完全读完了
intread(byte[] b)最多读取b.length字节的数据到b中,返回实际读到的数量;-1代表以及读完了
intread(byte[] b,int off,int len)最多读取len-off字节的数据到b中,放在从off开始,返回实际读到的数量;-1代表以及读完了
voidclose()关闭字节流

[注意事项]

  • 第二个read方法中给出了一个字节数组,代表的是,我们需要先准备好一个空数组,方法执行完毕之后,就会把读取到的数据填写到byte数组中,其中初始化byte数组的时候,可以指定一次性读取的字节数.也就是说,一次性读取字节数的多少取决于数组的长度,read会尽可能填满数组,如果填不满,能填多少填多少.

举例说明:取食堂打饭
取食堂打饭的时候,我们会先拿上一个空盘子,也就是固定大小的空数组,之后我们把这个盘子递给食堂的阿姨,也就是把空数组递给read方法,但是这里的食堂的阿姨不一样,这里的食堂阿姨不会手抖,会尽可能地把整个盘子都给你打满,如果剩下的饭不多了,食堂阿姨也没有办法,只能把盆子里剩下的所有的饭都给你打上,你也只能吃锅底了.(填不满,能填多少填多少)
在这里插入图片描述

  • 我们看到,前三个方法读取的时候,读取的应该是字节流,但是我们返回值的类型却是int类型,这是为什么呢?
    • 首先,在我们读到文件结束位置的时候,会返回-1,为了有余地表示-1,所以用int.
    • 可以确保杜处的字节,都是正数,都是按"无符号"的方式处理的.
  • 需要注意的是,我们在最后必须要关闭流,否则出现不可预知的bug.
  • InputStream只是一个抽象类,要使用的时候,还得有具体的类去实现.关于InputStream的实现类有很多,基本可以认为不同的输⼊设备都可以对应⼀个InputStream类,(包括蓝牙输入,网卡输入,硬盘输入)我们现在只关⼼从硬盘中读取,所以使用FileInputStream.
2.2.1.2 FileInputStream概述

构造方法:

签名说明
FileInputStream(File file)利⽤File构造⽂件输⼊流
FileInputStream(String name)利⽤⽂件路径构造⽂件输⼊流

第一个构造方法传入的是File对象,也就是通过File类提前创建好的文件对象来构造文件输入流.
第二个方法是通过传入文件的绝对路径或者是相对路径来构造文件输入流.

代码示例:输入效率问题

    public static void main(String[] args) throws IOException {File file = new File("./test.txt");file.createNewFile();try(OutputStream outputStream = new FileOutputStream("./test.txt")){byte[] array = {(byte) 'a',(byte)'b',(byte)'c',(byte)'d'};//注意强制类型转换outputStream.write(array);outputStream.flush();}try(InputStream inputStream = new FileInputStream("./test.txt")){//使用try()的方式来保证最后数据流一定会被关闭byte[] array = new byte[10];//一次读取10个字节while (true){int a = inputStream.read(array);//返回实际读取到的数量if (a == -1){//读取到文件的末尾-1,就停止读取break;}for (int i = 0; i < a; i++) {//这里之所以不写array.length是因为读到文件末尾的时候//最后实际读到的字节数不一定读慢10个字节System.out.println(array[i]);}}}}
public static void main(String[] args) throws IOException {File file = new File("./test.txt");file.createNewFile();try(OutputStream outputStream = new FileOutputStream("./test.txt")){byte[] array = {(byte) 'a',(byte)'b',(byte)'c',(byte)'d'};//注意强制类型转换outputStream.write(array);outputStream.flush();}try(InputStream inputStream = new FileInputStream("./test.txt")){//使用try()的方式来保证最后数据流一定会被关闭while (true){int a = inputStream.read();//返回实际读取到的数量if (a == -1){//读取到文件的末尾-1,就停止读取break;}System.out.println((char) a);}}}

注:OutputStream先不用管,我们先看InputStream的方法.

  • 第一种模式读取数据是每次读取10个字节的数据,但是第二个就是每次读取1个字节的数据.这两种方法相比,第一种方法的效率相对较高,是应为相对第一种方法,第二种方法读取硬盘的频率相对较高,读取硬盘的操作本来就是一个非常低效的操作,所以第二种方法效率相对第一种肯定低一些.
  • 我们知道,在读取完数据之后,输入流一定要被关闭,但是为了把我们的代码写得"优雅"一些,也就是不调用close方法即可关闭输入流,我们就可以把InputStream的创建放入try()中,但是可以这样做有着一定的前提条件,就是InputStream这个类实现了Closeable接口.
    public abstract class InputStream implements Closeable
2.2.1.3 利用Scanner进行字符读取

上述例子中,我们看到了对字符类型直接使用InputStream进行读取是非常麻烦且困难的,所以,我
们使用⼀种我们之前比较熟悉的类来完成该⼯作,就是Scanner类

构造⽅法说明
Scanner(InputStream is, String charset)使⽤charset字符集进行is的扫描读取

从上述Scanner的构造方法中,我们看到,Scanner的其中一个构造方法中,有一个参数就是输入流类型的参数.也就是说,我们在之前使用idea的控制台输入的一些内容,其实本质上就是一种输入流类型的数据.

public static void main7(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("./test.txt")){//之所以把Scanner放在try中,是因为最后它也要关闭try(Scanner scanner = new Scanner(inputStream)) {//这里Scanner传入的对象是一个输入流对象while (scanner.hasNext()){System.out.println(scanner.next());}}}}
2.2.1.4 OutputStream概述

方法:

修饰符及返回值类型⽅法签名说明
voidwrite(int b)写⼊要给字节的数据
voidwrite(byte[] b)将b这个字符数组中的数据全部写⼊os中
intwrite(byte[] b,int off,int len)将b这个字符数组中从off开始的数据写⼊os中,⼀共写len个
voidclose()关闭字节流
voidflush()重要:我们知道I/O的速度是很慢的,所以,⼤多的OutputStream为了减少设备操作的次数,在写数据的时候都会将数据先暂时写⼊内存的⼀个指定区域⾥,直到该区域满了或者其他指定条件时才真正将数据写⼊设备中,这个区域⼀般称为缓冲区。但造成⼀个结果,就是我们写的数据,很可能会遗留⼀部分在缓冲区中。需要在最后或者合适的位置,调⽤flush(刷新)操作,将数据刷到设备中。

[注意事项]

  • 上面方法的原理和InputStream类的方法相似,这里不再赘述.
  • OutputStream是一个抽象类,要使用具体的类来实现,现在还是只关心写的内容,所以使用FileOutStream
2.2.1.5 FileOutputStream概述

构造方法:

签名说明
FileOutputStream(File file)利⽤File构造⽂件输出流
FileOutputStream(String name)利⽤⽂件路径构造⽂件输出流

示例1:

public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./test.txt"){byte[] bytes = {(byte)'a',(byte)'b',(byte)'c'};outputStream.write(bytes);outputStream.flush();}}

[注意事项]

  • 按照写方式打开文件之后,会把==文件中的内容清空,==如果不想把文件中的内容清空,这时候我们就需要给输出流的构造方法中加上一个true,表示以"追加写"的方式打开.
public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./test.txt",true){byte[] bytes = {(byte)'a',(byte)'b',(byte)'c'};outputStream.write(bytes);outputStream.flush();}}
  • 如果我们在输出流中的write方法中写入的是数字,也会被ascii转化为字符.

2.2.2 字符流

字符流这里只可以读取文本文件.也就是读取的内容都是可以经过编码表编码为合法字符的.

2.2.2.1 Reader

构造方法:
Reader的构造方法和上述两个类的构造方法使用方法相同,这里不再赘述.
常用方法:
常用方法有两个,一个是read(),这个方法一次读取一个字符.一个是read(char[] cbuf),一次读取指定大小字符的字符串.
[注意事项]

  • 因为这里读取的是文本中的字符,这里常用的第二个read方法数组的类型是char[]类型,由于之前的字节流读取的是字节,所以是byte[].
  • 问题:写在文本文件中的中的如果是中文字符串,中文字符串的每一个字符是3字节,而char[]类型数组中的每一个位置是2字节,那么read(char[] cbuf)是如何做到精准读取的呢?
    解答:实际上,因为Java对上述的代码进行了编码转码,read操作在读取的时候,可以识别出String类型的每一个字符是utf-8编码格式(3字节/字),之后编译器就可以把utf-8格式的字符转码为Unicode(2字节/字)编码方式的字符.

代码演示:

public static void main10(String[] args) throws IOException {try(Reader reader = new FileReader("./test2.txt")){while (true){char[] chars = new char[10];int a = reader.read(chars);//在读取的时候,编译器会自动把汉字String中utf8的编码方式转为char中Unicode的编码方式//其中String中utf8编码方式是3字节,Unicode编码是2字节,char类型正好可以存下2字节if (a == -1){break;}for (int i = 0; i < a; i++) {System.out.println(chars[i]);}}}}
2.2.2.2 Writer

构造方法:略
常用方法:

方法用法
write()一次写一个字符
write(char[] cbuf)一次写多个
write(String str)一次写一个字符串

代码实例:

public static void main9(String[] args) throws IOException {try(Writer writer = new FileWriter("./test2.txt")){char[] chars = {'你','好','世','界'};writer.write(chars);writer.flush();}}

和OutputStream一样,它们在写内容的时候一样会清空文件内容,我们如果我们想重复写入,那么就要在构造方法后面加上true.

public static void main9(String[] args) throws IOException {try(Writer writer = new FileWriter("./test2.txt",true)){char[] chars = {'你','好','世','界'};writer.write(chars);writer.flush();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/12231.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(2024,MambaOut,Mamba 适合长序列,区分指标,不适合分类,适合检测和分割)视觉真的需要 Mamba 吗?

MambaOut: Do We Really Need Mamba for Vision? 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 3. 概念讨论 3.1 Mamba 适合哪些任务&#xff1f; 3.2 视觉识别任…

AtCoder Regular Contest 177

A - Excange 题意 用这些零钱能否不找零地买这些物品 思路 因为 500 5 100 10 50 50 10 500 1 5005\times 10010\times 5050\times 10500\times 1 5005100105050105001。 所以说&#xff0c;我们这道题可以采用贪心算法&#xff0c;优先取大的减去目前零钱最大的…

小美的区间删除

因为结尾0的个数取决于有多少对 ( 2 , 5 ) (2,5) (2,5) 相乘&#xff0c;那么对于下面例题&#xff0c;解题思路为&#xff1a; 1、将每个数字中的2和5剥离出来&#xff0c;然后用两个数组进行记录&#xff0c;然后其子数 ( 2 , 5 ) (2,5) (2,5)组成对至少为k个。 2、遍历每一…

echarts实现金价可视化大屏(项目实战)

前言 最近由于某种原因参加了一个比赛&#xff0c;三天时间肝出来一个可视化大屏项目&#xff08;无后端&#xff09;&#xff0c;代码已开源&#xff0c;但是还在比赛期间不知道会不会影响到 技术使用&#xff1a;html&#xff0c;css&#xff0c;js&#xff0c;echarts&#…

Jmeter+Grafana+Prometheus搭建压测监控平台

本文不介绍压测的规范与技术指标&#xff0c;本文是演示针对Jmeter如何将压测过程中的数据指标&#xff0c;通过Prometheus采集存储&#xff0c;并在Granfan平台进行仪表盘展示; 介绍 系统压测属于日常项目开发中的一个测试环节&#xff0c;使用测试工具模拟真实用户行为&…

Vue3实战笔记(18)—pinia注意事项和经验总结

文章目录 前言一、解构的注意事项二、注意创建和使用顺序总结 前言 在采用Pinia进行状态管理时&#xff0c;总结了一些关键注意事项与实战经验&#xff0c;旨在优化开发流程并确保高效利用其功能。这包括了正确规划存储结构、充分利用响应式优势、妥善处理模块化以促进代码可维…

Springboot+MybatisPlus如何实现分页和模糊查询

实现分页查询的时候我们需要创建一个config配置类 1、创建MybatisPlusConfig类 Configuration //表明这是一个配置类 ConditionalOnClass(Value{PaginationInterceptor.class} //ConditionalOnClass:当指定的类存在时&#xff0c;才会创建对应的Bean // 这里当PaginationInt…

Go-Zero定义API实战:探索API语法规范与最佳实践(五)

前言 上一篇文章带你实现了Go-Zero模板定制化&#xff0c;本文将继续分享如何使用GO-ZERO进行业务开发。 通过编写API层&#xff0c;我们能够对外进行接口的暴露&#xff0c;因此学习规范的API层编写姿势是很重要的。 通过本文的分享&#xff0c;你将能够学习到Go-Zero的API…

测试项目实战--安享理财2(Jmeter接口测试)

说明&#xff1a; 1.访问地址&#xff1a; 本项目实战使用的是传智播客的安享理财项目&#xff08;找了半天这个项目能免费用且能够满足测试实战需求&#xff09; 前台&#xff1a;http://121.43.169.97:8081/ 后台&#xff1a;http://121.43.169.97:8082/ &#xff08;点赞收藏…

前端工程化 - 快速通关 - vue

目录 npm 2.1环境 2.2命令 2.3使用流程 Vite 3.1简介 3.2实战 Vue3 4.1组件化 4.2SFC 4.3Vue工程 4.4基础使用 4.5进阶用法 4.6总结 npm npm 是 nodejs 中进行 包管理 的工具&#xff1b; 下载&#xff1a;Node.js — Run JavaScript Everywhere 2.1环境 ●安…

KubeKey 部署 K8s v1.28.8 实战

在某些生产环境下&#xff0c;我们仅需要一个原生的 K8s 集群&#xff0c;无需部署 KubeSphere 这样的图形化管理控制台。在我们已有的技术栈里&#xff0c;已经习惯了利用 KubeKey 部署 KubeSphere 和 K8s 集群。今天&#xff0c;我将为大家实战演示如何在 openEuler 22.03 LT…

使用DBeaver的第2天-使用sql导入数据

使用sql导入数据这块我会仔细的说一下 首先位置一定要放在库上&#xff08;实例&#xff09;&#xff0c;放在表上可不好使用哦 然后点击工具-再点击执行脚本 这样就执行成功了 但是如果你执行失败了&#xff0c;多半可能是因为本地没有部署mysql&#xff0c;记住只有本地有…

【IOS】swift新手踩坑总汇

这里写自定义目录标题 ESTabBarController_swiftQMUIKit ESTabBarController_swift Exception NSException * "调用了 pushViewController 但实际上没 push 成功&#xff0c;viewController&#xff1a;<HuangShan.ViewControllers: 0x106832a00>; superclass: EST…

【强训笔记】day23

NO.1 思路&#xff1a;直接计算结果&#xff0c;先计算怪物可以抗几次攻击&#xff0c;再计算勇士受到的伤害&#xff0c;如果勇士的攻击力大于等于怪物的血量&#xff0c;那么就可以击杀无数只&#xff0c;如果勇士的血量正好是受到攻击的整数倍&#xff0c;那么击杀的怪物数…

前端项目的准备工作

1.下载less或sass&#xff08;如果使用的话&#xff09; pnpm i -D less | pnpm i -D sass &#xff08;-D: 这是一个选项或标志&#xff0c;表示安装的软件包将被添加为开发依赖项&#xff08;devDependencies&#xff09;。开发依赖项是指在开发过程中需要使用的工具…

【信息系统项目管理师知识点速记】风险管理:实施风险应对

实施风险应对是确保项目风险管理计划得以执行的关键步骤,旨在通过监控和执行预先设定的策略来减轻威胁、抓住机遇,以及维持项目目标的一致性。此过程概括如下: 目标: 确保风险应对计划的执行。最小化单个风险的负面影响。最大化利用单个风险带来的机会。持续管理项目范围内…

web agent 学习 3:screen ai

学习论文&#xff1a;ScreenAI: A Vision-Language Model for UI and Infographics Understanding 摘要部分介绍了作者的screenai&#xff0c;是一个专门用于UI和信息图形理解的视觉语言模型。模型利用pix2struct灵活的补丁策略改进了PaLI架构&#xff0c;并在独特的数据集混合…

ubuntu编译pcl时报错

报错如下 cc1plus: warning: -Wabi wont warn about anything [-Wabi] cc1plus: note: -Wabi warns about differences from the most up-to-date ABI, which is also used by default cc1plus: note: use e.g. -Wabi11 to warn about changes from GCC 7 在网上找到了一封邮件…

国外新闻媒体投放:多元化媒体分发投稿平台-大舍传媒

引言 随着全球信息传播的加速和全球化的发展&#xff0c;国外新闻媒体的推广变得越来越重要。在这个数字化时代&#xff0c;多元化的媒体分发投放成为了有效推广的关键。本文将介绍大舍传媒在国外新闻媒体推广中的经验与策略。 国外新闻媒体的重要性 国外新闻媒体是获取国际…

insert语句的锁

insert … select 语句 CREATE TABLE t (id int(11) NOT NULL AUTO_INCREMENT,c int(11) DEFAULT NULL,d int(11) DEFAULT NULL,PRIMARY KEY (id),UNIQUE KEY c (c) ) ENGINEInnoDB;insert into t values (null, 1, 1); insert into t values (null, 2, 2); insert into t v…