javaSE————文件IO(2)、
文件内容的读写——数据流
我们对于文件操作使用流对象Stream来操作,什么是流对象呢,水流是什么样的,想象一下,水流的流量是多种的,可以流100ml,也可以流1ml,流对象就和水流很像,我们可以一次读取100个字节,或者一次读取1个字节;
1,字节流
1)inputStream
先来使用inputStream,这个是字节流的输入,inputStream是抽象类,和下面的outputStream是一样的,我们需要FileInputStream来实例化对象,FileInputStream的构造方法:
| 签名 | 说明 |
| FileInputStream(File file1) | 可以使用file构造文件输入流 |
| FileInputStream(String str) | 也可以使用文件路径构造输入流 |
那么inputStream有啥方法呢:
| 返回类型 | 签名 | 说明 |
| int | read() | 一次就读一个字节,读完了返回-1 |
| int | read(byte[] byte) | 一次读字节数组这么长的数据,返回-1就说明读完了 |
| int | read(byte[] byte,int start,int len) | 一次读取start到len的数据,读完了返回-1 |
| void | close() | 关闭输入流 |
用代码展示输入流:我们这里注意使用这些方法会抛异常,
InputStream inputStream = null;try {inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识点/Demo/QQ截图20240915161600.png");} catch (FileNotFoundException e) {throw new RuntimeException(e);} finally {inputStream.close();}
这里推荐使用try-with-resources,可以自动去close,为啥我们一定要去close呀,之间学数据结构都不用像c一样嗷嗷释放,因为文件操作不属于内存管理,GC垃圾回收不管他,我们嘚自己去关闭,不关闭他有什么影响呢,还记得进程中PCB中的文件描述符表吗,我们每打开一个程序就会在文件描述符表上自动创建一个固定长度的顺序表,就会申请一个表项,这个不会去扩容的,一直申请,不关闭,表项就没了;
}try (InputStream inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识" +"点/Demo/QQ截图20240915161600.png")){while (true){int a = inputStream.read();if(a==-1){break;}System.out.println(a);}}
我们在try中实例对象就相当于打卡了这个文件,如果FileInputStream爆红了,就说明文件不存在了,代码是一次只读取一个字符的情况,读到数据的时候,就会把读到的字符返回给a,因为是字节,所以会返回0-255的数值,在试试一次读取多个字节:
try (InputStream inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识" +"点/Demo/QQ截图20240915161600.png")){while (true){byte[] bytes = new byte[20];int a = inputStream.read(bytes);if(a==-1){break;}for (int i = 0; i < 20; i++) {System.out.print(bytes[i]+" ");}System.out.println();}}
我们创建一个字节数组,每次读取固定byte.length长度的字符,再输出,看看结果

此外呢,我们还可以通过Scanner来读取,我们在网络编程TCP协议中常常使用Scanner来代替intputStream,但是这里不太行,因为,Scanner会根据inputStreamReader把字节流转化为字符流,我们传的是一个图片,图片是二进制指令,我们需要遵守他们字节的编码方法,我们现在重新弄一个路径,试试读取字符;

我们在test中写3个哈哈哈;
InputStream inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt");Scanner scanner = new Scanner(inputStream);while (scanner.hasNext()){String a = scanner.next();System.out.print(a+" ");}
![]()
2)outputStream
outputStream就是字节流的输出了,同样也是一个抽象类,需要FileOutputStream来辅助实例对象,FileOutputStream的构造方法是和FileIntputStream一样的,我们来看看OutputStream的的方法:
| 返回值 | 签名 | 说明 |
| void | write(int b) | 写入所给的字节数据 |
| void | write(byte[] b) | 写入长度为b.length的字节数据 |
| int | write(byte[] b,int set,int len) | 将字节数组从Set开始,写入len个长度 |
| void | close() | 关闭字节流 |
| void | flush() |
这里的flush我们拿出来单独说,这个是什么方法呢,我们文件IO操作的数据是很慢的,我们不可能去等这个操作,一个一个的把这些数据写入到设备中,所以我们会先把数据攒到缓冲区中,等到缓冲区满了之后我们再把这些数据一起写入设备,所以我们可以使用这个操作,来冲刷缓冲区,不等他满了,直接把数据写入设备;
还是使用代码来看看:
try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt")){outputStream.write(97);outputStream.write(98);outputStream.write(98);} catch (IOException e) {throw new RuntimeException(e);}
我们写入几个字符,应该是abb;

test文档中出现了abb,哎不对呀,我们之前不是在这写了哈哈哈三个字吗,哪去了,我们的write操作是会覆盖之前的内容的,如果想要接着写我们要使用追加模式
try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt",true)){outputStream.write(76);} catch (IOException e) {throw new RuntimeException(e);}
实例化的构造方法中写true,就可以追加的写了;

这里多了一个l,再试试多行的写入
try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt",true)){byte[] bytes = new byte[]{99,98,97,96,95};outputStream.write(bytes);} catch (IOException e) {throw new RuntimeException(e);}

我们还可以试试,如果我们没有这个test文件会怎么样呢,怎么去写入呢,
try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){byte[] bytes = new byte[]{99,98,97,96,95};outputStream.write(bytes);} catch (IOException e) {throw new RuntimeException(e);}
我们写不存在的test4;


它自己创建了对应的文件并且写入了数据;
读数据有Scanner,那么写有没有对应的呢?有的兄弟有的,像这样的‘’‘’‘’‘’哈哈,不开玩笑了,我们还可以使用PrintWriter,来上代码:
try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){PrintWriter printWriter = new PrintWriter(outputStream);printWriter.print(98);printWriter.println(99);printWriter.flush();} catch (IOException e) {throw new RuntimeException(e);}

也是可以的;
2,字符流
我们使用字节流读取二进制数据,我们为啥还要字符流呢,通过编码方式,直接得到一堆字符不香吗;
1)Reader
我们使用Reader读数据,
public static void main(String[] args) {try(Reader reader = new FileReader("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){while (true){char[] chars = new char[1024];int b = reader.read(chars);if(b==-1){break;}for (int i = 0; i < b; i++) {System.out.print(chars[i]);}}} catch (IOException e) {throw new RuntimeException(e);}}

这就是我往test中放的,我们要注意java的编码和idea的编码方式,我这里的都是utf-8,如果不同的话是识别不出来的;
2)Writer
我们使用Writer来写入数据:
try(Writer writer = new FileWriter("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){char[] chars = new char[]{'H','E','l','l','o'};writer.write(chars);} catch (IOException e) {throw new RuntimeException(e);}
2,练习
我们来几个小练习
1)扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否 要删除该⽂件
public class Demo2 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入要找的目录");String rootDir = scanner.next();File file = new File(rootDir);if(!file.isDirectory()){System.out.println("这不是个目录");return;}System.out.println("请输入要删除的关键字");String key = scanner.next();find(file,key);}public static void find(File rootDir,String key){File[] files = rootDir.listFiles();if(files==null){return;}for (File file:files){System.out.println("正在遍历"+file.getAbsoluteFile());if(file.isFile()){dealFile(file,key);}else {find(file,key);}}}public static void dealFile(File file,String key){if(file.getName().contains(key)){System.out.println("发现文件,是否要删除呢,删除输入y");Scanner scanner = new Scanner(System.in);String s = scanner.next();if (s.equals("y")){file.delete();}else {return;}}else {return;}}
}
代码实现,我们现在藏几个文件:

"C:\cctalk\java代码容易犯错的知识点\Demo\demo2\新建文件夹\test4.txt"
看看他能不能把5个带关键字的都找到,


成功找到了;
2)进行普通文件的复制
"C:\cctalk\java代码容易犯错的知识点\Demo\test4.txt"
"C:\cctalk\java代码容易犯错的知识点\Demo\test1.txt"
我们把后面的文件复制到这个新建文件夹中;
public class Demo3 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入源文件路径");String src = scanner.next();File file = new File(src);if (!file.isFile()){System.out.println("输入的不是源文件路径或者源文件不存咋");return;}System.out.println("请输入目标文件路径");String destPath = scanner.next();File file1 = new File(destPath);if(!file1.getParentFile().isDirectory()){System.out.println("输入的目标文件路径的父目录不存在");return;}System.out.println(file.getAbsoluteFile());System.out.println(file1.getAbsoluteFile());try (InputStream inputStream = new FileInputStream(file);OutputStream outputStream =new FileOutputStream(file1)){while (true){byte[] bytes = new byte[1024];int a = inputStream.read(bytes);if(a==-1){break;}outputStream.write(bytes,0,a);}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}
我们就能看到


text1的数据复制到test4上了;
3)扫描指定内容并找到名称或者内容包含指定字符的文件;
C:\cctalk\java代码容易犯错的知识点
"C:\cctalk\java代码容易犯错的知识点\Demo\demo2\demo3\java.txt"
"C:\cctalk\java代码容易犯错的知识点\Demo\demo2\demo3\demo4\214.txt"
我们在第一个目录中找后面两个,第三个的内容包含java关键字的:
public class Demo4 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入要搜索的内容,输入目录");String src = scanner.next();File file = new File(src);if(!file.isDirectory()){System.out.println("输入的不是目录");return;}System.out.println("请输入关键字");String key = scanner.next();find(file,key);}public static void find(File file,String key){File[] files = file.listFiles();if(file==null){return;}for (File file1:files){if (file1.isFile()){dealFile(file1,key);}else {find(file1,key);}}}public static void dealFile(File file,String k){if (file.getName().contains(k)){System.out.println("文件名包含" + file.getName());return;}StringBuffer stringBuffer = new StringBuffer();try (Reader reader = new FileReader(file)){while (true){char[] chars = new char[1024];int a = reader.read(chars);if (a==-1){break;}stringBuffer.append(chars,0,a);}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}if(stringBuffer.indexOf(k)>=0){System.out.println("文件内容包含"+file.getName());}}
}

OK啦
相关文章:
javaSE————文件IO(2)、
文件内容的读写——数据流 我们对于文件操作使用流对象Stream来操作,什么是流对象呢,水流是什么样的,想象一下,水流的流量是多种的,可以流100ml,也可以流1ml,流对象就和水流很像,我…...
前端常问的宏观“大”问题详解(二)
JS与TS选型 一、为什么选择 TypeScript 而不是 JavaScript? 1. 静态类型系统:核心优势 TypeScript 的静态类型检查能在 编译阶段 捕获类型错误(如变量类型不匹配、未定义属性等),显著减少运行时错误风险。例如&…...
[创业之路-343]:创业:一场认知重构与组织进化的双向奔赴
目录 前言:关键词: 一、重构企业认知框架: 1、认知框架的顶层设计——六大维度生态模型 2、认知重构的精密设计——五层结构化模型 第一层:战略层(脑) 第二层:运营层(躯干&…...
智慧电力:点亮未来能源世界的钥匙
在科技日新月异的今天,电力行业正经历着前所未有的变革。智慧电力,作为这一变革的核心驱动力,正逐步改变着我们对电力的认知和使用方式。它不仅是电力行业的一次技术革新,更是推动社会可持续发展、实现能源高效利用的重要途径。 智…...
架构师面试(二十三):负载均衡
问题 今天我们聊微服务相关的话题。 大中型微服务系统中,【负载均衡】是一个非常核心的组件;在微服务系统的不同位置对【负载均衡】进行了实现,下面说法正确的有哪几项? A. LVS 的负载均衡一般通过前置 F5 或是通过 VIP keepa…...
CSS3学习教程,从入门到精通, CSS3 列表控制详解语法知识点及案例代码(24)
CSS3 列表控制详解 CSS 列表控制的语法知识点及案例代码的详细说明,包括 list-style-type、list-style-image、list-style-position 和 list-style 的用法。 1. list-style-type 属性 list-style-type 属性用于设置列表项标记的类型。 语法 list-style-type: v…...
NSSCTF(MISC)—[justCTF 2020]pdf
相应的做题地址:https://www.nssctf.cn/problem/920 binwalk分离 解压文件2AE59A.zip mutool 得到一张图片 B5F31内容 B5FFD内容 转换成图片 justCTF{BytesAreNotRealWakeUpSheeple}...
坚持“大客户战略”,昂瑞微深耕全球射频市场
北京昂瑞微电子技术股份有限公司(简称“昂瑞微”)是一家聚焦射频与模拟芯片设计的高新技术企业。随着5G时代的全面到来,智能手机、智能汽车等终端设备对射频前端器件在通信频率、多频段支持、信道带宽及载波聚合等方面提出了更高需求…...
LiteDB 数据库优缺点分析与C#代码示例
LiteDB 是一个轻量级的 .NET NoSQL 嵌入式数据库,完全用 C# 开发,支持跨平台(Windows、Linux、MacOS),并提供类似于 MongoDB 的简单 API。它以单文件形式存储数据,类似于 SQLite,支持事务和 ACID 特性,确保数据的一致性和可靠性。 优缺点分析 优点: 轻量级与嵌入式:…...
上海SMT贴片技术解析与行业趋势
内容概要 随着长三角地区电子制造产业集群的快速发展,上海作为核心城市正引领着SMT贴片技术的革新浪潮。本文聚焦表面组装技术在高密度互连、微间距贴装等领域的突破性进展,通过解析焊膏印刷精度控制、元件定位算法优化等核心工艺,展现上海企…...
HTML5和CSS3的一些特性
HTML5 和 CSS3 是现代网页设计的基础技术,它们引入了许多新特性和功能,极大地丰富了网页的表现力和交互能力。 HTML5 的一些重要特性包括: 新的语义化标签: HTML5 引入了一些重要的语义化标签如 <header>, <footer>, <articl…...
Linux系统中快速安装docker
1 查看是否安装docker 要检查Ubuntu是否安装了Docker,可以使用以下几种方法: 方法1:使用 docker --version 命令 docker --version如果Docker已安装,输出会显示Docker的版本信息,例如: Docker version …...
每日c/c++题 备战蓝桥杯(最长上升子序列)
点击题目链接 题目描述 给出一个由 n(n≤5000) 个不超过 1e6 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。 最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。 输入格式 第一行,一个整数…...
蓝桥杯—质数
质数 质数是一个只有1和它本身2个因数 代码实现 //求质数 #include<bits/stdc.h> using namespace std; bool zhishu(int n) {if(n1){cout<<"1不是质数";return false;}else if(n>1){for(int i2;i<sqrt(n);i){if(n%i0){cout<<n<<&q…...
CP15 协处理器
ARMv7-A 一共支持 16 个协处理器,编号从 CP0~CP15。这里仅对CP15进行描述。 1、ARMv7-A 协处理器 ARMv7-A 处理器除了标准的 R0~R15,CPSR,SPSR 以外,由于引入了 MMU、TLB、Cache 等内容,ARMv7-A 使用协处理器来对这些…...
网络运维学习笔记(DeepSeek优化版)026 OSPF vlink(Virtual Link,虚链路)配置详解
文章目录 OSPF vlink(Virtual Link,虚链路)配置详解1. 虚链路核心特性2. 基础配置命令3. 状态验证命令3.1 查看虚链路状态3.2 验证LSDB更新 4. 关键技术要点4.1 路径选择机制4.2 虚链路的链路优化 5. 环路风险案例 OSPF vlink(Virtual Link&a…...
简单介绍一下Unity中的material和sharedMaterial
在Unity中,材质(Material)是定义物体外观的关键组件,它决定了物体的颜色、纹理、光照效果等属性。Renderer组件(如MeshRenderer或SpriteRenderer)通过材质来渲染游戏对象的外观。Unity提供了两种访问材质的…...
小智机器人关键函数解析,Application::MainLoop() 用于持续监听事件组中的事件,并根据不同的事件触发相应的操作
以下是对 Application::MainLoop() 函数的详细解释: 源码: // The Main Loop controls the chat state and websocket connection // If other tasks need to access the websocket or chat state, // they should use Schedule to call this function …...
设计模式之适配器模式(二):STL适配器
目录 1.背景 2.什么是 STL 适配器? 3.函数对象适配器 3.1.std::bind 3.2.std::not1 和 std::not2 3.3.std::mem_fn 4.容器适配器 4.1.std::stack(栈) 4.2.std::queue(队列) 4.3.std::priority_queue(优先队列࿰…...
【区块链安全 | 第十六篇】类型之值类型(三)
文章目录 函数类型声明语法转换成员合约更新时的值稳定性示例 函数类型 函数类型是函数的类型。函数类型的变量可以通过函数进行赋值,函数类型的参数可以用来传递函数并返回函数。 函数类型有两种类型:内部函数和外部函数。 内部函数只能在当前合约内调…...
设计模式——设计模式理念
文章目录 参考:[设计模式——设计模式理念](https://mp.weixin.qq.com/s/IEduZFF6SaeAthWFFV6zKQ)参考:[设计模式——工厂方法模式](https://mp.weixin.qq.com/s/7tKIPtjvDxDJm4uFnqGsgQ)参考:[设计模式——抽象工厂模式](https://mp.weixin.…...
Kubernetes对象基础操作
基础操作 文章目录 基础操作一、创建Kubernetes对象1.使用指令式命令创建Deployment2.使用指令式对象配置创建Deployment3.使用声明式对象配置创建Deployment 二、操作对象的标签1.为对象添加标签2.修改对象的标签3.删除对象标签4.操作具有指定标签的对象 三、操作名称空间四、…...
Java与代码审计-Java基础语法
Java基础语法 package com.woniuxy.basic;public class HelloWorld {//入口函数public static void main(String[] args){System.out.println("Hello World");for(int i0;i< args.length;i){System.out.println(args[i]);}} }运行结果如下: 但是下面那个没有参数…...
Xenium | 细胞邻域(Cellular Neighborhood)分析(fixed radius)
上节我们介绍了空间转录组数据分析中常见的细胞邻域分析,CN计算过程中定义是否为细胞邻居的方法有两种,一种是上节我们使用固定K最近邻方法(fixed k-nearest neighbors)定义细胞Neighborhood,今天我们介绍另外一种固定半径范围内(fixed radiu…...
Python:爬虫概念与分类
网络请求: https://www.baidu.com url——统一资源定位符 请求过程: 客户端,指web浏览器向服务器发送请求 请求:请求网址(request url);请求方法(request methods);请求头(request header)&…...
[Linux实战] Linux设备树原理与应用详解
Linux设备树原理与应用详解 一、设备树概述 1.1 什么是设备树 设备树(Device Tree,简称DT)是一种描述硬件资源的数据结构,它通过一种树状结构来描述系统硬件配置,包括CPU、内存、总线、外设等硬件信息。设备树最初在…...
用Nginx实现负载均衡与高可用架构(整合Keepalived)
前言 在分布式架构中,负载均衡和高可用是保障系统稳定性的两大核心能力。本文将深入讲解如何通过Nginx实现七层负载均衡,并结合Keepalived构建无单点故障的高可用架构。文末附完整配置模板! 一、Nginx负载均衡实现方案 1. 核心原理 Nginx通…...
SQLMesh调度系统深度解析:内置调度与Airflow集成实践
本文系统解析SQLMesh的两种核心调度方案:内置调度器与Apache Airflow集成。通过对比两者的适用场景、架构设计和操作流程,为企业构建可靠的数据分析流水线提供技术参考。重点内容包括: 内置调度器的轻量级部署与性能优化策略Airflow集成的端到…...
Excel 中 INDEX 和 VLOOKUP 的对比
INDEX 和 VLOOKUP 都是 Excel 中常用的查找函数,但它们的用途和灵活性有所不同。 1. 相同点 均可用于查找数据:都能根据某个条件返回目标值。 支持精确匹配:均可使用 0 或 FALSE 进行精确匹配。 2. 不同点 特性VLOOKUPINDEX MATCH查找方向…...
Multism TL494仿真异常
仿真模型如下:开关频率少了一半,而且带不动负载,有兄弟知道为什么吗 这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码…...

