当前位置: 首页 > news >正文

Java 文件操作与IO流

文件

文件有两个概念,在广义来看就是操作系统上对硬件和软件资源抽象为文件。
在侠义上来看,就是我们保存在硬盘上的文件

在这里我们讨论的是狭义的文件,在外面的硬盘上的文件细分又可以分为二进制文件和文本文件,文本文件可以通过码表转换成现实生活中有意义的文字,而二进制文件则是我们看不懂的文件。

我们可以通过记事本打开一个文件,如果里面的乱码则说明这是二进制文件,如果你能看懂说明这是文本文件。

其实文件本质上都是二进制文件,上面的文件只是根据文件是否表达人类语言的意义来进行划分的,在计算机里文件的存储都是以二进制的方式进行存储的。

绝对路径:就是文件的具体位置信息,没有省略
相对路径:./text.txt 就在当前路劲下的 text.txt
…/text.txt 表示当前路劲的上一个路径

windows 操作系统路径表示支持斜杠 / 和 反斜杠 \ 两种符号,其他操作系统只能使用 斜杠 / 来对路径进行分割
我们使用 斜杠 / 来分割路径就可以了,反正 windows 操作系统也能支持。

File

在Java 中标准库给我们提供了可以操作文件或者目录的类 File。

注意 File 不仅仅可以操作文件,也可以操作目录。

下面是 File 的构造方法:
在这里插入图片描述

这里如果你使用的是相对路径进行传参,那这个相对路径的基准值就是程序存在在哪个文件夹下,这个路径就是基准值,因为基准值是根据程序运行而改变的。

File 提供的方法:
在这里插入图片描述

import java.io.File;
import java.io.IOException;public class Demo1 {public static void main(String[] args) throws IOException {File file = new File("./test.txt");System.out.println(file.getPath());System.out.println(file.getParent());System.out.println(file.getAbsolutePath());System.out.println(file.getCanonicalPath());System.out.println(file.exists());}
}

在这里插入图片描述

先要注意即使没有存在 file 这个文件,File 在实例化的时候是没有问题的。


在这里插入图片描述

    public static void main(String[] args) throws IOException {File file = new File("./test.txt");System.out.println(file.createNewFile());}

如果文件没有存在,会成功创建并且返回 true,如果文件已经存在就会创建失败并且返回false.


    public static void main(String[] args) throws IOException {File file = new File("./test.txt");file.createNewFile();System.out.println(file.exists());System.out.println(file.delete());System.out.println(file.exists());}

在这里插入图片描述

这个就是简单的删除,没什么好说的。


    public static void main(String[] args) throws IOException {File file = new File("./test.txt");file.createNewFile();System.out.println(file.exists());file.deleteOnExit();System.out.println(file.exists());}

在这里插入图片描述

deleteOnExit() 这个是等到进程结束才删除这个文件。


    public static void main(String[] args) {File file = new File("./text.txt");file.mkdir();}

在这里插入图片描述
在这里插入图片描述

mkdir 是创建一级目录,如果涉及到多级目录的创建是无法完成的,多级目录的创建要使用 mkdirs() 方法。


    public static void main(String[] args) {File file = new File("./text.txt/2005/04/02");file.mkdirs();}

在这里插入图片描述


list() 和 listFile() 都是获取当前目录下的所有文件,只是返回值类型不同,list() 是返回 String 类型,listFile() 则是返回 File 类型。

    public static void main(String[] args) {File file = new File("D:/code/Java/java_study/J2024_11_2");String[] list = file.list();System.out.println(Arrays.toString(list));File[] list2 = file.listFiles();System.out.println(Arrays.toString(list2));}

在这里插入图片描述

IO 流

字节流

字节流是以字节为单位的读取,主要用于二进制文件的读写。

字符流在骄Java中有两个类需要掌握,一个是 InputStream ,另一个是 OutputStream

首先我们要知道这两个类都是抽象类,是不能直接实例化的。
在这里插入图片描述
在这里插入图片描述

接着我们还要知道输入流是用来读取还是写入???
输入输出的定义是我们站在CPU 的视角,数据往 CPU 来就是输入,数据从 CPU 离开就是 输出。
因此输入流 InputStream 就是用来读取数据的,OutputStream 是用来写入数据的。

最后,我们知道文件的打开是会消耗资源的,当我们使用完文件之后我们需要关闭资源,避免资源泄漏,其实这也是因为操作系统在每次打开文件,就会占用文件描述表的一个位置,并且这个文件描述表是不会自动扩容的,所以能打开的文件有限,不能只打开不关闭文件,这样文件描述表在某一个时刻就会被消耗殆尽导致后续再打开文件的操作失败引发 BUG。

我们关闭文件除了可以使用 close 方法之外,我们可以直接在 try(打开文件的代码){},当出了 try 代码块就会自动关闭文件,这是因为Java 的 IO 流的类 实现了 Closable 接口


既然我们不能直接实例化 InputStream 和 OutputStream 的话,我们可以使用 FileInputStreamFileOutputStream 来实例化(因为它们分别继承了InputStream 和 OutputStream),听名字大家应该知道这两个类其实就是用来操作文件的。
在这里插入图片描述
在这里插入图片描述


FileInputStream

InputStream 提供的方法:
在这里插入图片描述

FileInoutStream 的构造方法:
在这里插入图片描述
代码演示:
首先在 test.txt 文件中写上 hello java

在这里插入图片描述

read() 演示:

    public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("./test.txt");) {int n = 0;while (n != -1) {n = inputStream.read();System.out.println(n);}}}

在这里插入图片描述


read(byte[] b) 演示:这个会首先填满 byte 数组,并且返回一个数值表示读取了多少个字节。

这种也叫做输出型参数,就是我们传入的引用参数到一个方法里面,这个方法会直接修改我们传入的引用类型参数,并且这个参数的修改也影响到方法外部的参数,这种参数我们称之为输出型参数。

    public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("./test.txt");) {byte[] b = new byte[1024];while(true) {int n = inputStream.read(b);if(n == -1) {break;}for (int i = 0; i < n; i++) {System.out.println(b[i]);}}}}

在这里插入图片描述

FileOutputStream

OutputStream 提供的方法
在这里插入图片描述
在这里插入图片描述

FileOutputStream 的构造方法和 FileInputStream 的参数是一样的。

如果文件不存在的话,FileOutputStream 会自动创建好文件,然后进行写操作。

    public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./test.txt");) {outputStream.write(65);outputStream.write(66);outputStream.write(67);}}

在这里插入图片描述


    public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./test.txt");) {byte[] b = {97,98,99};outputStream.write(b);}}

在这里插入图片描述

当你进行写操作的时候,是直接覆盖之前的内容再进行写操作,如果你想要进行的是追加写的话,在构造方法中加上一个 true,这样就是追加写。

    public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./test.txt",true);) {byte[] b = {97,98,99};outputStream.write(b);}}

在这里插入图片描述

字符流

字符流是以字符为单位进行存储的,主要用于文本文件的读写

字符流一样给我们提供了两个抽象类 ReaderWriter,我们可以通过实例化 FileReaderFileWriter

我们先将文本内容改为 你好
在这里插入图片描述

Reader

Reader 提供的方法:
在这里插入图片描述
read() 是读取一个字符,read(char[] chuf) 是将字符数组填充读取到的字符,read(CharBuffer target) 其中的CharBuffer 是对char[] 进行了封装。
read(char[] cbuf, int off, int len) 就是指定将读取到的字符填充到字符数组的哪个位置。

    public static void main(String[] args) throws IOException {try(Reader reader = new FileReader("./test.txt")) {while(true) {char[] b = new char[1];int n = reader.read(b);if(n == -1) {break;}for (int i = 0; i < n; i++) {System.out.println(b[i]);}}}}

在这里插入图片描述

在Java中使用 utf8进行编码,明明一个中文占3个字节,为什么我用 char(两个字节) 就可以读取出来???
字符流读取到的是文件中原始的数据也就是 两个汉字占 6 个字节(utf8 编码),字符流会根据文件的编码方式进行解析,read() 一次就会读取到 3 个字节,返回的时候会针对这 3 个字节进行转码,也就是先将 这个 3 个字节对照 utf8 码表查询到 ‘你’ 这个汉字之后,read 又将 “你” 这个汉字在 unicode 这个码表进行查询得到 unicode 编码,这样就是两个字节,最后将这两个字节的数值返回到 char 变量中。

    public static void main(String[] args) throws IOException {try(Reader reader = new FileReader("./test.txt")) {char[] arr = new char[2];while(true) {int n = reader.read(arr);if(n == -1) {break;}for (int i = 0; i < n; i++) {System.out.println(arr[i]);}}}}

在这里插入图片描述

Writer

Writer 提供的方法:
在这里插入图片描述

    public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("./test.txt")) {writer.write("hello world");}}

在这里插入图片描述

你想要追加写,也是一样加上 true 就可以了。

    public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("./test.txt",true)) {writer.write("hello world");}}

在这里插入图片描述

实战演练

扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件

在遍历文件的时候,我们只能遍历到一层的文件,如果该文件夹里面还有文件的话,我们需要进行递归才能获取到内部的文件。

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Demo1 {public static void main(String[] args) {System.out.println("请输入指定目录:");Scanner scan = new Scanner(System.in);String str = scan.next();File file = new File(str);if(!file.isDirectory()) {System.out.println("您输入的不是目录或者该目录不存在...");return;}System.out.println("请输入指定的字符:");String token = scan.next();List<File> list = new ArrayList<>();scanFile(file, token);}private static void scanFile(File file, String token) {File[] ret = file.listFiles();if(ret == null) {return;}for (int i = 0; i < ret.length; i++) {if(ret[i].isDirectory()) {scanFile(ret[i], token);} else {delFile(ret[i], token);}}}private static void delFile(File file, String token) {if(file.getName().contains(token)) {System.out.println("该文件包含你指定的字符内容:" + file.getAbsoluteFile());System.out.println("是否进行删除:Y / N");Scanner scan = new Scanner(System.in);String ret = scan.next();if(ret.equals("Y")) {file.delete();}}}
}

在这里插入图片描述


进行普通文件的复制

import java.io.*;
import java.util.Scanner;public class Demo2 {public static void main(String[] args) throws IOException {System.out.println("请输入你要复制的文件路径:");Scanner scan = new Scanner(System.in);String str = scan.next();File file = new File(str);if(!file.isFile()) {System.out.println("你输入的不是文件或者该文件不存在...");return;}System.out.println("请输入你要复制的路径:");String end = scan.next();File file2 = new File(end);if(!file2.getParentFile().isDirectory()) {System.out.println("要复制到的文件路径不存在...");return;}byte[] b = new byte[1024];try(InputStream inputStream = new FileInputStream(str);OutputStream outputStream = new FileOutputStream(end);) {while(true) {int n = inputStream.read(b);if(n == -1) {break;}outputStream.write(b,0, n);}}System.out.println("复制成功");}
}

在这里插入图片描述
在这里插入图片描述


扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

import java.io.*;
import java.util.Scanner;public class Demo3 {public static void main(String[] args) throws IOException {System.out.println("请输入你要指定的目录");Scanner scan = new Scanner(System.in);String str = scan.next();File file = new File(str);if(!file.isDirectory()) {System.out.println("你输入的不是目录或者该目录不存在");return;}System.out.println("请输入你要指定的内容:");String token = scan.next();scanDir(file, token);}public static void scanDir(File rootFile, String token) throws IOException {File[] list = rootFile.listFiles();for(File file: list) {if(file.isDirectory()) {scanDir(file, token);} else {checkFile(file, token);}}}private static void checkFile(File file, String token) throws IOException {if(file.getName().contains(token)) {System.out.println("文件名包含指定关键字:" + file.getAbsolutePath());return;}Reader reader = new FileReader(file);StringBuilder check = new StringBuilder();char[] b = new char[1024];while(true) {int n = reader.read(b);if(n == -1) {break;}check.append(b);}if(check.toString().contains(token)) {System.out.println("文件内容包含指定关键字:" + file.getAbsoluteFile());}}
}

在这里插入图片描述

相关文章:

Java 文件操作与IO流

文件 文件有两个概念&#xff0c;在广义来看就是操作系统上对硬件和软件资源抽象为文件。 在侠义上来看&#xff0c;就是我们保存在硬盘上的文件 在这里我们讨论的是狭义的文件&#xff0c;在外面的硬盘上的文件细分又可以分为二进制文件和文本文件&#xff0c;文本文件可以通…...

探索开源MiniMind项目:让大语言模型不再神秘(1)

简介&#xff1a; 声明&#xff1a;本人非此项目作者&#xff0c;仅仅是探索项目&#xff0c;分享项目。如有不妥&#xff0c;请联系我删除&#xff01; 原项目地址&#xff1a;GitHub - jingyaogong/minimind: 「大模型」3小时完全从0训练26M的小参数GPT&#xff0c;个人显卡即…...

Android 大疆面经

Android 大疆面经 文章目录 Android 大疆面经一面 一面 自我介绍问项目聊了10分钟View的绘制流程MVC&#xff0c;MVP&#xff0c;MVVM的区别view和viewmodel的通信&#xff0c;除了databing还有其他的方式面向对象和面向过程的区别工厂模式和策略模式&#xff0c;哪些框架使用…...

【2024-10-31-2024-11-03】LeetCode刷题——python语法基础题

&#x1f4dd;前言说明&#xff1a; ●本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;主要跟随B站作者灵茶山的视频进行学习&#xff0c;专栏中一篇文章为B站对应的一个视频 题目主要为B站视频内涉及的题目以及B站视频中提到的“课后作业”。 ●文章中的理…...

【算法】二分查找

目录 一、概念 二、思路 三、边界问题 一、概念 在一本书中查找某一页&#xff0c;我们总是倾向于先翻到整本书的中间&#xff0c;然后根据当前页数判断我们想要找的页在当前页的左半本中还是右半本中&#xff0c;接着继续翻到剩下半本书的中间...... 这就是二分查找思想在…...

第十五章 Vue工程化开发及Vue CLI脚手架

目录 一、引言 二、Vue CLI 基本介绍 三、安装Vue CLI 3.1. 安装npm和yarn 3.2. 安装Vue CLI 3.3. 查看 Vue 版本 四、创建启动工程 4.1. 创建项目架子 4.2. 启动工程 五、脚手架目录文件介绍 六、核心文件讲解 6.1. index.html 6.2. main.js 6.3. App.vue 一、…...

【Grafana】Grafana 基础入门

Grafana 简介 什么是Grafana Grafana 是一跨平台的开源的可视化分析工具&#xff0c;是目前网络架构和应用分析中最流行的时序数据展示工具&#xff0c;主要用于大规模指标数据的可视化展示。 它是用Go语言开发&#xff0c;可以做数据监控和数据统计&#xff0c;带有告警功能…...

如何获取页面上所有input框

要获取页面上所有的<input>框&#xff0c;你可以使用JavaScript。这通常可以通过查询DOM&#xff08;文档对象模型&#xff09;来实现&#xff0c;有几种方法可以做到这一点&#xff0c;包括使用document.querySelectorAll、document.getElementsByTagName或document.get…...

0-ARM Linux驱动开发-字符设备

一、字符设备概述 Linux 系统中&#xff0c;设备被分为字符设备、块设备和网络设备等。字符设备以字节流的方式进行数据传输&#xff0c;数据的访问是按顺序的&#xff0c;一个字节一个字节地进行读取和写入操作&#xff0c;没有缓冲区。例如&#xff0c;终端&#xff08;/dev…...

使用 Faster Whisper 和 Gradio 实现实时语音转文字

随着人工智能技术的进步&#xff0c;语音识别已经成为最热门的研究领域之一。如何实现高效、准确的实时语音转文字功能&#xff0c;是许多开发者关注的重点。本文将介绍如何使用 Faster Whisper 和 Gradio 这两个强大工具&#xff0c;快速构建一个实时语音转文字应用。 Faster…...

redis v6.0.16 安装 基于Ubuntu 22.04

redis安装 基于Ubuntu 22.04 本文演示如何在ubuntu22.04下&#xff0c;安装redis v6.0.16&#xff0c;并配置测试远程访问。 Step1 更新环境 sudo apt updateStep2 安装redis sudo apt install redis-server -yStep3 启动 sudo systemctl restart redissudo systemctl sta…...

Milvus - 内存索引类型详解

1. 背景概述 在大规模数据处理和向量相似性搜索场景中&#xff0c;内存索引的使用显著提升了查询速度和效率。Milvus 提供了多种内存索引类型&#xff0c;以满足不同场景下的性能需求。本文将介绍 Milvus 支持的各种内存索引类型及其适用场景、配置参数和使用方法。 2. 为什么…...

【STM32】按键控制LED 光敏传感器控制蜂鸣器

文章目录 前置知识按键介绍传感器模块硬件电路按键硬件电路传感器模块硬件电路 C语言数据类型在Keil中的对应写法C语言枚举 按键控制LED接线图Hardware文件夹&#xff08;模块化编程&#xff09;LED驱动程序封装Key(按键)驱动程序封装 main.c源文件 光敏传感器控制蜂鸣器接线图…...

flutter-防抖

在Flutter中实现输入框的防抖功能&#xff0c;通常是为了减少用户输入时触发的事件数量&#xff0c;特别是在进行网络请求时。防抖&#xff08;Debounce&#xff09;意味着在用户停止输入一段时间后才触发事件。以下是实现输入框防抖的一种方法&#xff1a; 1、使用Debounce类…...

什么是贪心算法

贪心算法&#xff08;Greedy Algorithm&#xff09;是一种逐步构建解决方案的方法&#xff0c;在每一步选择中都作出局部最优的选择&#xff0c;希望最终能够获得全局最优解。贪心算法的核心思想是贪心选择性质&#xff0c;即每次选择当前看来最好的解&#xff0c;不考虑未来可…...

YOLOv6-4.0部分代码阅读笔记-effidehead_lite.py

effidehead_lite.py yolov6\models\heads\effidehead_lite.py 目录 effidehead_lite.py 1.所需的库和模块 2.class Detect(nn.Module): 3.def build_effidehead_layer(channels_list, num_anchors, num_classes, num_layers): 1.所需的库和模块 import torch import t…...

重学SpringBoot3-整合 Elasticsearch 8.x (一)客户端方式

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 这里写目录标题 1. 为什么选择 Elasticsearch&#xff1f;2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述2.1 准备工作2.2 添加依赖 3. Elasticsearch 客户端配置方式…...

极简实现酷炫动效:Flutter隐式动画指南第三篇自定义Flutter隐式动画

目录 前言 一、TweenAnimationBuilder 二、使用TweenAnimationBuilder实现的一些动画效果 1.调整透明度的动画 2.稍微复杂点的组合动画 3.数字跳动的动画效果 前言 上两节博客分别介绍了Flutter中的隐式动画的基础知识以及使用隐式动画实现的一些动画效果。当系统提供的隐…...

无人机维护保养、部件修理更换技术详解

无人机作为一种精密的航空设备&#xff0c;其维护保养和部件修理更换是确保飞行安全、延长使用寿命的重要环节。以下是对无人机维护保养、部件修理更换技术的详细解析&#xff1a; 一、无人机维护保养技术 1. 基础构造理解&#xff1a; 熟悉无人机的基本构造&#xff0c;包括…...

xilinx vitis 更换硬件平台——ZYNQ学习笔记5

1、重新生成硬件信息 2、选择带有bit信息 3、设施路径和名字 4、打开更新硬件选项 5、选择新的硬件信息 6、打开系统工程界面 7、复位硬件信息 更新完毕...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...