【JavaEE】文件操作(InputStream、OutputStream)

news2024/12/23 17:38:01

 

  • 博主简介:想进大厂的打工人
  • 博主主页:@xyk:
  • 所属专栏: JavaEE初阶 

在Java中总会用到文件操作,比如从盘符读写文件,按字节和字符进行数据读写,那么你真的认识什么是文件路径吗?平时谈到的“文件”,指的都是硬盘上的文件,文件IO这里也是操作硬盘了,本篇文章将详细讲解如何对文件系统操作,文件内容操作,文件操作需要用到的哪些API~~

JavaEE中的文件操作和IO,之前我们学习的代码,定义个变量,其实就是在内存上申请空间,Mysql中主要是操作硬盘的,文件IO也是操作硬盘!!

硬盘(外存)和内存相比:

速度:内存比硬盘快很多

空间:内存空间比硬盘小

成本:内存比硬盘贵

持久化:内存掉电后数据丢失,外存掉电后数据还在


目录

文章目录

一、认识文件

1.1 树型结构组织 和 目录

1.2 文件路径

二、文本文件vs二进制文件

三、文件系统操作

3.1 光看知识点,跟听天书一样,那么我来举个例子来理解吧:

4.1 文件内容操作

4.2 不带参数的read方法

4.3 write方法写数据

五、 文件查找内容程序练习

5.1 控制台输入要查询的目录和词

5.2 递归的进行目录/文件的遍历

5.3 文件读取

5.4 测试


一、认识文件

我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般。

 文件除了有数据内容之外,还有一部分信息,例如文件名、文件类型、文件大小等并不作为文件的数据而存在,我们把这部分信息可以视为文件的元信息

 1.1 树型结构组织 和 目录

同时,随着文件越来越多,对文件的系统管理也被提上了日程,如何进行文件的组织呢,一种合乎自然的想法出现了,就是按照层级结构进行组织 —— 也就是我们数据结构中学习过的树形结构。这样,一种专门用来存放管理信息的特殊文件诞生了,也就是我们平时所谓文件夹(folder)或者目录(directory)的概念。

1.2 文件路径

这是文件系统上一个文件/目录,具体位置~

目录(专业术语)==文件夹(通俗的说法)

计算机的目录是由层级结构的

 可以看到,文件系统,是以树形结构来组织文件和目录的!!N叉树

文件路径:就是从树根节点出发,沿着树杈,一路往下走,到达目标文件,此时这中间经过的内容

Windows都是从“此电脑”起头的

表示路径的时候,可以把“此电脑” 省略,直接从 盘符 开始表示

C:\javacode\java-ee\springDemo

 实际表示路径,是通过一个字符串表示,每个目录之间使用 \ 或者 / 来分割

\ 反斜杠 只是在windows中适用,代码中写需要写出 \\ ,需要转义字符的~

/ 斜杠 通常使用这种,推荐使用

从盘符开始,一层一层往下找,这个过程,得到的路径,叫做绝对路径

从给定的某个目录出发,一层一层往下找,这个过程得到的路径,叫做相对路径

一定要明确,基准目录(工作目录) 是什么!!!

假如工作目录是这个,此时找到

 

 相对路径表示,./JavaEE/springDemo

如果工作目录是

 要找到

 相对路径表示,../2.多线程(基础).md

. 相对路径中,是一个特殊符号,表示当前目录

..也是特殊符号,表示当前目录的上级目录~~

  • . . / . . / 代表上一级目录的上一级目录~

关于路径,非常关键~~

相对路径,一定要明确,工作目录是什么

相比之下,绝对路径,就可以理解成,以“此电脑”为工作路径

文件系统上,任何一个文件,对应的路径,是唯一的!!

不会存在,俩个路径相同,但是文件不同的情况!!

Windows上可以认为,路径和文件是一一对应的

路径就相当于一个文件的“身份标识”

二、文本文件vs二进制文件

文本文件,存储的是文本,文本文件的内容都是由ascii字符构成的

 对应ascii来说,表示范围0-127

文本文件里存储的数据,就是遵守ascii或者其他字符集编码,所得到的文件!!

本质上存的是字符

二进制文件存储的是二进制数据,则没有任何字符集的限制,存什么都行

简单粗暴的方式:

之间使用记事本来打开某个文件,如果你看到的内容能看懂,就是文本文件

看不懂,乱乱的,就是二进制文件(不仅仅是char类型)

txt,文本文件

.java / .c 也是文本文件

.class 二进制文件

.exe 二进制文件

jpg,MP3二进制文件

三、文件系统操作

Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不
代表真实存在该文件。
File对象是硬盘上的一个文件的“抽象”表示~~

文件是存储在硬盘上的,直接通过代码操作硬盘,不太方便

就在内存中创建一个对应的对象,操作这个内存中改的对象,就可以间接的影响到硬盘的文件情况了~~

构造File对象
我们先来看看 File 类中的构造方法和方法

构造方法

签名说明
File(File parent, String
child)
根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname)根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者
相对路径
File(String parent, String
child)
根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用
路径表示

方法

修饰符及返回
值类型
方法签名说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径
booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是一个目录
booleanisFile()判断 File 对象代表的文件是否是一个普通文件
booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返
回 true
booleandelete()根据 File 对象,删除该文件。成功删除后返回 true
voiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到
JVM 运行结束时才会进行
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象
表示
booleanmkdir()创建 File 对象代表的目录
booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目
booleanrenameTo(File
dest)
进行文件改名,也可以视为我们平时的剪切、粘贴操
booleancanRead()判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限

3.1 光看知识点,跟听天书一样,那么我来举个例子来理解吧:

 

 IDEA工作路径就是项目所在目录

写相对路径,就是以

这一级为基准,来展开的~~ 

2.

 

exists()判断 File 对象描述的文件是否真实存在
isDirectory()判断 File 对象代表的文件是否是一个目录
isFile()判断 File 对象代表的文件是否是一个普通文件

 3.

 

mkdir创建 File 对象代表的目录,mkdirs创建 File 对象代表的目录,如果必要,会创建中间目录

4.

 

list()返回 File 对象代表的目录下的所有文件名
listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象
表示

5.

  

renameTo(File
dest)
进行文件改名,也可以视为我们平时的剪切、粘贴操

四、文件内容操作

4.1 文件内容操作

有很多类,一组类

针对文本文件,提供了一组类,统称为“字符流”(典型代表,Reader,Writer)读写的基本单位是字符

针对二进制文件,提供了一组类,统称为“字节流”(典型代表,InputStream,OutputStream)读写的基本单位是字节

每种流对象,又分成俩种,

输入的:Reader,InputStream

输出的:Writer,OutputStream

 InputStream 概述

抽象类,不能直接实例化!!! 

方法

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

FileInputStream 概述

构造方法

签名说明
FileInputStream(File file)利用 File 构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

切记要进行,非常重要!!

文件这里的资源,需要手动释放!!

主要是“文件描述符”,记载了当前线程都打开了哪些文件~~

每次打开一个文件,就会在这个表里,申请到一个位置~

这个表就可以当作一个数组,数组下标就是文件描述符表,数组元素就是这个文件在内核中的结构体的表示~~

 之所以能这么写,是因为InputStream实现了一个特定的接口Closeable

try with resources

带有资源的try操作,会在try代码块结束,自动执行close关闭操作

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(刷新)操作,将数据刷到设备中。

4.2 不带参数的read方法

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

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

 

read读到末尾会返回-1

read和write可以一次读写多个字节,使用byte[]表示

4.3 write方法写数据

 

五、 文件查找内容程序练习

 5.1 控制台输入要查询的目录和词

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //1.先输入一个要搜索的目录
        System.out.println("请输入要搜索的根目录:");
        File rootDir = new File(scanner.next());
        if (!rootDir.isDirectory()){
            System.out.println("输入有误,您输入的目录不存在!");
            return;
        }
        //2.让用户输入一个要查询的词
        System.out.println("请输入要查询的词:");
        String word = scanner.next();

        //3.递归的进行目录/文件的遍历
        scanDir(rootDir,word);
    }
  1. 根据根目录构造File对象
  2. 如果这个file对象不是目录或者不存在的话,则说明输入错误,直接返回退出程序
  3. 如果是目录,输入要关键字
  4. 调用scanDir方法对目录进行扫描(自己实现)

5.2 递归的进行目录/文件的遍历

private static void scanDir(File rootDir, String word) {
        File[] files = rootDir.listFiles();
        if (files == null){
            //空目录
            return;
        }
        for (File f:files) {
            System.out.println("当前搜索到:" + f.getAbsolutePath());
            if (f.isFile()){
                //普通文件
                //打开文件,读取内容,比较关键词
                String content = readFile(f);
                if (content.contains(word)){
                    System.out.println(f.getAbsolutePath()+"包含关键字");
                }
            }else if (f.isDirectory()){
                //是目录,进行递归
                scanDir(f,word);
            }else {
                continue;
            }
        }
    }


1.普通文件,打开文件,读取内容,比较关键词

2.是目录,进行递归

3.空目录退出

5.3 文件读取

private static String readFile(File f) {
        // 读取文件的整个内容, 返回出来.
        // 使用字符流来读取. 由于咱们匹配的是字符串, 此处只能按照字符流处理, 才是有意义的.
        StringBuilder stringBuilder = new StringBuilder();
        try (Reader reader = new FileReader(f)){
            while (true){
                int c = reader.read();
                if (c == -1){
                    break;
                }
                stringBuilder.append((char)c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

读取文件的整个内容, 返回出来.
使用字符流来读取. 由于咱们匹配的是字符串, 此处只能按照字符流处理, 才是有意义的.

5.4 测试

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

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

相关文章

mybatis实现CRUD详解(使用mapper映射文件实现增删改查)

mybatis实现CRUD详解(使用mapper映射文件实现增删改查) 创建maven项目&#xff1a;项目结构如图所示 准备数据库表&#xff1a; 准备pom.xml所需的依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.…

快速弄懂RPC

快速弄懂RPC 常见的远程通信方式远程调用RPC协议RPC的运用场景和优势 常见的远程通信方式 基于REST架构的HTTP协议以及基于RPC协议的RPC框架。 远程调用 是指跨进程的功能调用。 跨进程可以理解为一个计算机节点的多个进程或者多个计算机节点的多个进程。 RPC协议 远程过…

C++string类

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容讲解了C中的string类以及类内的一些常用函数 Cstring类 文章…

k8s_3节点集群部署

背景 近期想在自己电脑上部署一套3节点K8s 作为自己平时的学习测试环境。 本来想看一下有没有比较便捷的部署方式如&#xff1a; rancherdesktop: https://docs.rancherdesktop.io/zh/next/getting-started/installation/ sealos: https://www.sealos.io/docs/getting-started…

【超算/先进计算学习】日报3

目录 今日已完成任务列表遇到的问题及解决方案任务完成详细笔记作业管理系统 slurm作业管理系统及常用用户命令节点状态查询/作业提交命令作业队列查询/作业取消命令任务练习 调试器 GDB实时调试core 文件调试 对自己的表现是否满意简述下次计划其他反馈 今日已完成任务列表 4-…

Spring的体系结构

Spring的体系结构 一、Spring简介1. Spring介绍1.1 为什么要学1.2 学什么1.3 怎么学 2. 初识Spring2.1 Spring家族2.2 Spring发展史 3. Spring体系结构3.1 Spring Framework系统架构图3.2 Spring Framework课程学习路线 4. Spring核心概念4.1 目前我们代码存在的问题4.2 核心概…

『Linux从入门到精通』第 ⑫ 期 -深入了解冯诺依曼体系结构与操作系统(Operator System)

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f337;计算机之父——冯诺依曼&#x1f337;冯诺依曼体系结构&#x1f33a;木桶效应 &#x1f337;操作系统(Operator System)&#x1f33a;如何理解操作系统&#x1f33a;系统调用和库函数概念 &#x1f490;专栏导…

论文结构商讨

论文查重 pass软件 提出问题 1、由于选取的算法太多了&#xff0c;不知道是简单介绍&#xff0c;还是深入介绍 希望找到一个具体的模板 2、数据库要是用一个就在前面介绍&#xff0c;用不一样的就在每章里面分别介绍 4、数据集介绍放在那个具体位置&#xff1f; 如果可以画出…

蓝精灵事件来袭: 深受喜爱的蓝色角色来 Web3 啦!

起源于漫画并成为国际知名的卡通和电影明星的蓝色x小家伙正在进入 NFT 舞台。 作者&#xff1a;Coindesk——Toby Bochan 因漫画、卡通片和电影而闻名的热门动画系列“蓝精灵”正在展开新的冒险&#xff0c;由蓝精灵协会推出一系列新的非同质化通证&#xff08;NFT&#xff09;…

汽车ECU的内部构成与功能模块

摘要&#xff1a; ECU作为与外部通信的接口&#xff0c;为了通过微控制器运算实现符合实际状态的最佳控制&#xff0c;需要检测外部状态的输入手段及实际控制驱动的输出手段。 1. 常规功能模块 ① 电源&#xff1a;向ECU内的各模块提供稳定的电压&#xff08;5V、3V等&#xf…

sequelize + Nodejs + MySQL 的简单用法

How to Use Sequelize ORM in NodeJS - Tutorial 1 Sequlize 简介 Sequelize 是最流行的可以与 Nodejs 一起使用的一种关系数据库 ORM (Object-relational mapping 对象关系映射)&#xff0c;Mongoose 是 MongoDB 的 ORM. Sequelize 的作用&#xff0c;简单地说&#xff0c;就…

Netty编解码器,Netty自定义编解码器解决粘包拆包问题,Netty编解码器的执行过程详解

文章目录 一、编解码器概述1、编解码器概述2、编码器类关系图3、解码器类关系图 二、以编解码器为例理解入站出站1、Server端2、Client端3、编解码器3、执行查看结果4、注意事项 三、Netty其他内置编解码器1、ReplayingDecoder2、其他编码器3、内置编解码器处理粘包拆包问题 四…

[LeetCode复盘] LCCUP‘23春季赛 20230422

[LeetCode复盘] LCCUP23春季赛 20230422 一、总结二、 1. 补给马车1. 题目描述2. 思路分析3. 代码实现 三、2. 探险营地1. 题目描述2. 思路分析3. 代码实现 四、 3. 最强祝福力场1. 题目描述2. 思路分析3. 代码实现 五、 4. 传送卷轴1. 题目描述2. 思路分析3. 代码实现 六、 5…

REDIS03_AOF概述、工作流程、写回策略、正常异常流程、重写机制、配置文件详解

文章目录 ①. AOF - 概述作用②. AOF - 工作流程③. 缓冲区 - 写回策略④. 配置文件说明(6 VS 7)⑤. 正常、异常恢复⑥. AOF - 优劣势⑦. AOF - 重写机制⑧. AOF优化配置项详解⑨. RBD和AOF共存模式 ①. AOF - 概述作用 ①. 官网介绍 ②. 以日志的形式来记录每个写操作,将Red…

解决RabbitMQ的The channelMax limit is reached. Try later.

The channelMax limit is reached. Try later.顾名思义就是channel达到数量限制 查看源码得出 大概意思就是&#xff1a; 默认最大通道数&#xff1b;2047&#xff0c;因为它在服务器端是第2048个&#xff0c;每个连接用于协商和错误通信。 也可以在rabbitmq的管控台看出 总结…

单页面与路由

目录 &#xff08;一&#xff09;什么是SPA应用&#xff1f; &#xff08;二&#xff09;路由 &#xff08;1&#xff09;什么是路由&#xff1f; &#xff08;2&#xff09;路由的分类 &#xff08;3&#xff09;路由的安装和使用 &#xff08;三&#xff09;、路由的使…

微服务 - 搭建Consul集群服务,Consul配置中心

传统配置文件的弊端 静态化配置&#xff0c;例如env文件配置文件无法区分环境配置文件过于分散历史版本无法查看 配置中心如何解决的呢?配置中心的思路是把项目中的配置参数全部放在一个集中的地方来管理&#xff0c;并提供一套标准的接口&#xff0c;当各个服务需要获取配置…

d2l 使用attention的seq2seq

这一章节与前面写好的function关联太大&#xff0c;建议看书P291. 这章节主要讲述了添加attention的seq2seq,且只在decoder里面添加&#xff0c;所以全文都在讲这个decoter 目录 1.训练 2.预测 1.训练 #save class AttentionDecoder(d2l.Decoder):"""带有注…

HTTP与HTTPS相关介绍(详细)

HTTP与HTTPS相关介绍 HTTP与HTTPS简述HTTPS和HTTP的区别主要如下HTTPS的工作原理前言工作步骤总结 HTTPS的缺点SSL与TLSSSL&#xff1a;TLS&#xff1a;TLS和SSL的关系 对称加密与非对称加密对称加密非对称加密 HTTP与HTTPS简述 超文本传输协议&#xff08;Hyper Text [Transf…

如何无侵入地引入第三方组件?

做java开发的小伙伴都知道&#xff0c;java的生态比较繁荣&#xff0c;有各种各样的第三方组件来满足我们日常的开发需求。很多常用的中间件(redis&#xff0c;kafka等)都提供java的开发接口&#xff0c;而且这些接口通常会被封装成比较好用的组件来满足我们使用这些中间件的场…