当前位置: 首页 > 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、复位硬件信息 更新完毕...

使用pandas实现合并具有共同列的两个EXCEL表

表1&#xff1a; 表2&#xff1a; 表1和表2&#xff0c;有共同的列“名称”&#xff0c;而且&#xff0c;表1的内容&#xff08;行数&#xff09;<表2的行数。 目的&#xff0c;根据“名称”列的对应内容&#xff0c;将表2列中的“所处行业”填写到表1相应的位置。 实现代…...

153页PPT麦肯锡咨询流程管理及企业五年发展布局构想与路径规划

麦肯锡咨询的流程管理以其高度结构化、数据驱动和结果导向的核心特点著称&#xff0c;旨在为客户提供清晰、可行且价值最大化的解决方案。其典型流程可概括为以下几个关键阶段&#xff1a;下载资料请查看文章中图片右下角信息 问题界定与结构化&#xff1a; 这是流程的基石。麦…...

【C++11(上)】—— 我与C++的不解之缘(三十)

一、C11 这里简单了解一下C发展好吧&#xff1a; C11是C的第二个大版本&#xff0c;也是自C98以来最重要的一个版本。 它引入了大量的更改&#xff0c;它曾被人们称为C0x&#xff0c;因为它被期待在2010年之前发布&#xff1b;但在2011年8月12日才被采纳。 C03到C11花了8年时间…...

硬件学习笔记--66 MCU的DMA简介

DMA&#xff08;Direct Memory Access&#xff0c;直接存储器访问&#xff09;是MCU中一种重要的数据传输机制&#xff0c;它允许外设与存储器之间或存储器与存储器之间直接传输数据&#xff0c;而无需CPU的持续干预。 1、DMA的基本原理 1.1 核心概念&#xff1a; 1&#xf…...

【C盘瘦身】给DevEco Studio中HarmonyOSEmulator(鸿蒙模拟器)换个地方,一键移动给C盘瘦身

文章目录 一、HarmonyOSEmulator的安装路径二、修改路径 一、HarmonyOSEmulator的安装路径 之前安装了华为的DevEco Studio&#xff0c;当时没注意&#xff0c;后来C盘告急&#xff0c;想着估计是鸿蒙的模拟器占用空间比较大&#xff0c;一检查还真是躺在C盘。路径如下&#x…...

PCB设计教程【入门篇】——电路分析基础-元件数据手册

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 目录 前言 一、数据手册的重要…...

机器学习数据降维方法

1.数据类型 2.如何选择降维方法进行数据降维 3.线性降维&#xff1a;主成分分析&#xff08;PCA&#xff09;、线性判别分析&#xff08;LDA&#xff09; 4.非线性降维 5.基于特征选择的降维 6.基于神经网络的降维 数据降维是将高维数据转换为低维表示的过程&#xff0c;旨在保…...

SpringBoot系列之RabbitMQ 实现订单超时未支付自动关闭功能

系列博客专栏&#xff1a; JVM系列博客专栏SpringBoot系列博客 RabbitMQ 实现订单超时自动关闭功能&#xff1a;从原理到实践的全流程解析 一、业务场景与技术选型 在电商系统中&#xff0c;订单超时未支付自动关闭功能是保障库存准确性、提升用户体验的核心机制。传统定时任…...

【Web应用】若依框架:基础篇13 源码阅读-前端代码分析

文章目录 ⭐前言⭐一、课程讲解过程⭐二、自己动手实操⭐总结 标题详情作者JosieBook头衔CSDN博客专家资格、阿里云社区专家博主、软件设计工程师博客内容开源、框架、软件工程、全栈&#xff08;,NET/Java/Python/C&#xff09;、数据库、操作系统、大数据、人工智能、工控、网…...

商品模块中的多规格设计:实现方式与电商/ERP系统的架构对比

在商品管理系统中&#xff0c;多规格设计&#xff08;Multi-Specification Product Design&#xff09;是一个至关重要但又极具挑战性的领域。无论是面向消费者的电商系统&#xff0c;还是面向企业管理的ERP系统&#xff0c;对商品规格的处理方式直接影响库存管理、订单履约、数…...