【JavaEE】【IO】文件操作
目录
- 一、文件
- 1.1 文件的概念
- 1.2 文件的操作
- 1.3 路径
- 1.4 文件分类
- 二、Java中的文件元信息、路径操作
- 2.1 属性
- 2.2 构造方法
- 2.3 方法
- 2.3.1 文件路径
- 2.3.2 文件判断
- 2.3.3 文件创建删除
- 2.3.4 其他操作
- 三、文件读写操作
- 3.1 流(Stream)
- 3.1.1 字节流
- 3.1.1.1 InputStream
- 3.1.1.2 OutputStream
- 3.1.2 字符流
- 3.1.2.1 Reader
- 3.1.2.2 Writer
- 3.2 字节流字符流转换
- 四、自定义快读类
- 4.1 自定义快速读入
- 4.2 自定义快速输出

一、文件
1.1 文件的概念
在操作系统中会将“硬盘设备”和“软件资源”都抽象成文件。
在生活中提到的文件大多指硬盘的文件(像c盘里面的文件),就是硬盘上的数据抽象而成的。
1.2 文件的操作
在计算机上文件是由操作系统提供的“文件系统”来组织管理的,操作系统使用“目录”(也就是常说的文件夹)来管理文件的。目录是一种树形结构
1.3 路径
- 绝对路径:就是以C盘D盘(C: D:)这种盘符开头的路径。如"E:\植物大战僵尸"。
- 相对路径:此时需要先指定一个基准目录,然后看通过什么样的路径来到指定文件,这个路径就是相对路径,用点开头。此时用一个点表示当前目录,两个点表示当前目录上一级目录。
举例:
假如我们要找“E:\植物大战僵尸\pvzHE"目录下的"fonts"文件。
- 如果我们当前在“E:\植物大战僵尸\pvzHE"目录下,直接使用“.\fonts”
- 如果我们在“E:\植物大战僵尸”目录下,使用“.\pvzHE\fonts”
- 如果我们在"E:\植物大战僵尸\pvzHE\新建文件夹"目录下,使用“…\fonts”
不同场景下的基准目录:
- 在命令行操作,当前目录就是基准目录。
- 在idea操作项目目录就是基准目录。
- 在图形化工具上就要看实际情况了。
1.4 文件分类
在编程角度上将文件分为两类:
- 文本文件:文件中保存的都是字符串,保存的都是合法的字符(合法的字符就是符合当前字符集编码的字符)。
- 二进制文件:文件中保存的仅仅是二进制数据。
二、Java中的文件元信息、路径操作
Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。
2.1 属性
| 修饰符及类型 | 属性 | 说明 |
|---|---|---|
| static String | pathSeparator | 依赖于系统的路径分隔符,String 类型的表示 |
| static char | pathSeparator | 依赖于系统的路径分隔符,char 类型的表示 |
2.2 构造方法
| 签名 | 说明 |
|---|---|
| File(File parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例 |
| File(String pathname) | 根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径 |
| File(String parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用路径表示 |
2.3 方法
2.3.1 文件路径
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| String | getParent() | 返回 File 对象的父目录文件路径 |
| String | getName() | 返回 FIle 对象的纯文件名称 |
| String | getPath() | 返回 File 对象的文件路径 |
| String | getAbsolutePath() | 返回 File 对象的绝对路径 |
| String | getCanonicalPath() | 返回 File 对象的修饰过的绝对路径 |
2.3.2 文件判断
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| boolean | exists() | 判断 File 对象描述的文件是否真实存在 |
| boolean | isDirectory() | 判断 File 对象代表的文件是否是一个目录 |
| boolean | isFile() | 判断 File 对象代表的文件是否是一个普通文件 |
| boolean | canRead() | 判断用户是否对文件有可读权限 |
| boolean | canWrite() | 判断用户是否对文件有可写权限 |
2.3.3 文件创建删除
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| boolean | createNewFile() | 根据 File 对象,自动创建一个空文件。成功创建后返回 true |
| boolean | delete() | 根据 File 对象,删除该文件。成功删除后返回 true |
| void | deleteOnExit() | 根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行 |
2.3.4 其他操作
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| String[ ] | list() | 返回 File 对象代表的目录下的所有文件名 |
| File[ ] | listFiles() | 返回 File 对象代表的目录下的所有文件,以 File 对象表示 |
| boolean | mkdir() | 创建 File 对象代表的目录 |
| boolean | mkdirs() | 创建 File 对象代表的目录,如果必要,会创建中间目录 |
| boolean | renameTo(Filedest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操作 |
三、文件读写操作
在Java中对文件的读写操作使用流对象(stream)
3.1 流(Stream)
在标准库中提供的文件读写操作的类有很多,但可以分为两类。
3.1.1 字节流
字节流对应着二进制文件,每次读写的最小单位都是字节(Byte)。
字节流提供了两个父类(InputStream)(OutputStream)来供继承。
3.1.1.1 InputStream
InputStream在源码中是一个抽象类,不能直接new对象。提供了一个子类FileInputStream。

类需要传文件路径,如果文件没找到还会抛出FileNotFoundException异常。

方法简介
| 返回值 | 方法签名 | 说明 |
|---|---|---|
| int | read() | 读取一个字节的数据,返回 -1 代表已经完全读完了 |
| int | read(byte[ ] b) | 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了 |
| int | read(byte[ ] b, int off, int len) | 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了 |
| void | close() | 关闭字节流 |
3.1.1.2 OutputStream
默认打开一个文件会先清空,要继续写不清空在创建对象时传入true作为第二个参数。

OutputStream在源码中是一个抽象类,不能直接new对象。提供了一个子类FileOutputStream。

类需要传文件路径,如果文件没找到还会抛出FileNotFoundException异常。

方法
| 返回值 | 方法签名 | 说明 |
|---|---|---|
| void | write(int b) | 写入要给字节的数据 |
| void | write(byte[ ] b) | 将 b 这个字符数组中的数据全部写入 os 中 |
| int | write(byte[ ] b, int off, int len) | 将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个 |
| void | close() | 关闭字节流 |
| void | flush() | 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。 |
3.1.2 字符流
字符流对应着文本文件,每次读写的最小单位是字符(根据当前字符集来,一个中文字符在utf8就是3字节,GBK就是两字节)。
字符流就相当于对字节流进行了一个封装,自动帮我们把字节流中相邻几个字节转换成字符。
字符流提供了两个父类(Reader)(Writer)来供继承。
3.1.2.1 Reader
Reader在源码中是一个抽象类,不能直接new对象。提供了一个子类FileReader。

FileReader类需要传文件路径,如果文件没找到还会抛出FileNotFoundException异常。

Reader中读取字符常用是read方法,都会抛出IOException异常,介绍常用3种。
| 返回值 | 分法签名 | 说明 |
|---|---|---|
| int | read() | 读取一个字符,读取到返回ASCII值或者字符集编码值,没读取到返回-1 |
| int | read(char[ ] cbuf) | 读取多个字符,尽量将cbuf数组填满,返回读取到的字符个数,如果读完文件返回-1 |
| int | read(char[ ] cbuf, int off, int len) | l最多读len-off个,从数组off下标开始储存,返回读到的个数,如果读完文件返回-1 |
返回值说明:
int作为返回值时,返回的是一个2字节表示的,这时因为在Java中char类型是Unicode编码,而String是由utf8编码(String的编码集可改)。

创建了一个Reader对象要释放:对象名.close();
主要释放的是文件描述符表(在进程介绍PCB的主要属性),文件描述符表里面主要用顺序表(数组)来储存,如果一直不释放,里面数组被占满就会发生内存泄露。
但是如果直接就这么写,那如果上面代码抛出异常,就执行不到close,改进方法:
- try-finally处理:
Reader reader = new FileReader("d:/test.txt");
try {int n = reader.read();
} finally {reader.close();}
- try with resource
在定义对象时放入,出了try语句就会自动调用类实现的close方法(必须是实现了closeable接口的)。
try( Reader reader = new FileReader("d:/test.txt") ) {int n = reader.read();
}
3.1.2.2 Writer
默认打开一个文件会先清空,要继续写不清空在创建对象时传入true作为第二个参数。

InputStream在源码中是一个抽象类,不能直接new对象。提供了一个子类FileInputStream。

类需要传文件路径,如果文件没找到还会抛出IOException异常。

方法
| 返回值 | 方法签名 | 说明 |
|---|---|---|
| void | write(int c) | 写入要给文件的数据 |
| void | write(char[ ] cbuf) | 将 cbuf 这个字符数组中的数据全部写入 os 中 |
| int | write(byte[ ] cbuf, int off, int len) | 将 cbuf 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个 |
| void | write(String str) | 将 str 这个字符串中的数据全部写入 os 中 |
| void | write(String str, int off, int len) | 将 str 这个字符串中的数据从 off 开始的数据写入 os 中,一共写 len 个 |
| void | close() | 关闭字节流 |
| void | flush() | 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。 |
3.2 字节流字符流转换
使用Scanner工具类去读取文件中的字符。
try(InputStream inputStream = new FileInputStream("D:/test.txt")) {Scanner scanner = new Scanner(inputStream);String s = scanner.next();}
使用PrintWriter工具类去写入文件中的字符。
try(OutputStream outputStream = new FileOutputStream("D:/test.txt",true)) {PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println();}
四、自定义快读类
自定义快读类来解决我们做算法题的时候由于数据量过大的时候引起的超时问题。
4.1 自定义快速读入
我们使用Scanner去读IO设备文件,,而我们现在使用BufferedReader来开辟一个内存缓冲区,在内存中拿数据比IO设备要快得多。
步骤:
- 字节流转变为字符流,在存入内存缓冲区中。
BufferedReader bf = new BufferedReader(new InputStreamReader(system.in));
- 字符串裁剪对象,拿到内存缓冲区的字符串的必要对象。
StringTokenizer st = new StringTokenizer("");
- 详解next方法:相当于在内存缓冲区中拿一行数据,使用while循环来处理多行输入。
String next() throws IOException {while(!st.hasMoreTokens()) {st = new StringTokenizer(bf.readLine());}return st.nextToken();
}
- 其他直接返回对应的parse转换就行。
类代码:
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
class Read {StringTokenizer st = new StringTokenizer("");BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));String next() throws IOException {while(!st.hasMoreTokens()) {st = new StringTokenizer(bf.readLine());}return st.nextToken();}String nextLine() throws IOException {return bf.readLine();}int nextInt() throws IOException {return Integer.parseInt(next());}long nextLong() throws IOException {return Long.parseLong(next());}double nextDouble() throws IOException {return Double.parseDouble(next());}float nextFloat() throws IOException {return Float.parsefloat(next());}
}
4.2 自定义快速输出
跟自定义一样的优化方式。
public static PrintWriter out = new PrintWriter(new BufferedWriter(new OutPutStreamWriter(System.out)))
使用之后就直接 out.输出方法,输出方法与System.out一样。
相关文章:
【JavaEE】【IO】文件操作
目录 一、文件1.1 文件的概念1.2 文件的操作1.3 路径1.4 文件分类 二、Java中的文件元信息、路径操作2.1 属性2.2 构造方法2.3 方法2.3.1 文件路径2.3.2 文件判断2.3.3 文件创建删除2.3.4 其他操作 三、文件读写操作3.1 流(Stream)3.1.1 字节流3.1.1.1 I…...
commonjs和esmodule的导入导出细节
CommonJS和ES Module是JavaScript中两种不同的模块系统,它们在导入导出细节上存在差异,以下是两者的具体对比以及方便区分记忆的方法: 1. 导入导出细节 CommonJS 导出:使用module.exports或exports对象来导出模块中的变量、函数…...
【热门】用ChatGPT做智慧农业云平台——农业ERP管控系统
随着科技的进步,原有农业种植方式已经不能满足社会发展的需要,必须对传统的农业进行技术更新和改造。经过多年的实践,人们总结出一种新的种植方法——温室农业,即“用人工设施控制环境因素,使作物获得最适宜的生长条件,从而延长生产季节,获得最佳的产出”。这种农业生产方式…...
Android从上帝视角来看PackageManagerService
戳蓝字“牛晓伟”关注我哦! 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章,技术文章也可以有温度。 前言 阅读该篇之前,建议先阅读下面的系列文章: Android深入理解包管理–PackageManagerService和它的“小伙伴…...
阵列式位移计与传统测斜仪相比的优势
在岩土工程监测领域,位移测量是确保工程质量和安全的重要环节。传统的测斜仪,如活水平固定测斜仪和固定式测斜仪,尽管在一定程度上满足了工程监测的需求,但某些方面限制了其应用范围。随着阵列式位移计这种新型的传感器的出现&…...
第7章 网络请求和状态管理
一、Axios 1 Axios概述 Axios是一个基于Promise的HTTP库,可以发送get、post等请求,它作用于浏览器和Node.js中。当运行在浏览器时,使用XMLHttpRequest接口发送请求;当运行在Node.js时,使用HTTP对象发送请求。 Axios的…...
苍穹外卖学习笔记(二十七)
客户催单 OrderController /*** 催单*/GetMapping("/reminder/{id}")ApiOperation("催单")public Result reminder(PathVariable("id") Long id) {orderService.reminder(id);return Result.success();}OrderServer /*** 催单*/void reminder(L…...
使用exe4j打包jar包生成exe文件,GUI应用详细使用教程
使用exe4j打包jar包生成exe文件,GUI应用详细使用教程 exe4j应用教程使用方式搞副业 exe4j应用教程 《exe4j 下载地址》 exe4j是一个功能强大的多平台 Java 安装程序生成器,它可以为 Java 应用程序生成本机安装程序和应用程序启动器。exe4j 的优点在于它的易用性、广…...
go jwt 用户登录和返回用户信息 token ----important!!!
1.每一行代码都有详细注释,解释了其功能和作用。这些注释可以帮助你理解代码如何工作,特别是在处理用户登录、生成 JWT、验证 JWT 和返回用户信息的过程中。 package main // 指定这个文件是一个可执行程序import ("fmt" …...
OpenCV高级图形用户界面(12)用于更改指定窗口的大小函数resizeWindow()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::resizeWindow() 函数用于更改指定窗口的大小。这使得你可以根据需要调整窗口的宽度和高度。 注释 指定的窗口大小是指图像区域的大小。工具栏…...
babylonjs shader学习之copy shadertoy案例
shadertoy案例: 准备 const onSceneReady (scene: Scene) > {const light new HemisphericLight(light, new Vector3(0, 1, 0), scene);light.intensity 0.7;Effect.ShadersStore[planeMatVertexShader] precision highp float;attribute vec3 position;attr…...
Leetcode 1137. 第 N 个泰波那契数
原题链接:Leetcode 1137. 第 N 个泰波那契数 代码1: class Solution { public:int a[40];int tribonacci(int n) {a[0]0;a[1]1;a[2]1;if(n<1) return n;if(a[n]) return a[n];a[n]tribonacci(n-1)tribonacci(n-2)tribonacci(n-3);return a[n];} };代…...
Rust 语言持续崛起,即将冲击 TIOBE 指数前十,能否成为编程语言新王者?
Rust 语言持续崛起,即将冲击 TIOBE 指数前十,能否成为编程语言新王者? 2024 年 10 月,全球编程语言 TIOBE 排行榜再次更新,各大编程语言在各自领域中继续发挥着独特的优势。官方的标题是: Rust排名稳步攀升…...
Linux 手撕线程池
前言 线程池 是 池化技术 中很典型的一个,它旨在高效的管理和复用线程资源!在现在的计算机体系中,线程是执行任务(调度)的基本单位。然而,频繁的创建和销毁线程也会带来较大的开销,包括系统资源…...
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十五集:制作更多地图,更多敌人,更多可交互对象
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、第一个代表性场景 1.制作更多敌人2.制作更多可交互对象二、第二个代表性场景 1.制作更多敌人2.制作更多可交互对象三、第三个代表性场景 1.制作更多敌人2.制…...
在Openshift上安装MetalLB
1.部署MetalLB Operator 2.部署AddressPool addresses 必须和ocp节点在同一网段 apiVersion: metallb.io/v1beta1 kind: AddressPool metadata:name: metallb-ipaddressnamespace: metallb-system spec:addresses:- 192.168.1.51-192.168.1.60- 192.168.1.61-192.168.1.70aut…...
mysql其他对象
一、存储引擎 mysql的存储引擎包括: InnoDB,MyISAM,Memory(Heap),Archive,CSV,NDB Cluster 常用的只有前两个。 InnoDB与MyISAM的区别: InnoDB 简介:Inn…...
英语单词之社会生活之聚会
一些关于聚会的单词和短语 句子 English中文What’s the plan?计划是什么?I’m going out with some friends.我要跟几个朋友一起出去。I don’t really feel like going out.我不是很想出去。What time suits you ?你什么时间合适?Where shall we m…...
Qt - 地图相关 —— 1、加载百度在线地图(附源码)
效果图 开始加载地图 1、百度地图开发者网站中注册,获取密钥 2、进入开发文档中 将下图内容保存到本地文件中,文件名为"index.html"文件即可。接着将内容中的“您的密钥”改为刚刚创建应用出来的AK密钥即可。 然后双击打开若在浏览器中正常看到下图右侧地图则说明没…...
Elasticsearch 简单使用
Elasticsearch 安装和基本操作 一、引言 Elasticsearch 是一个基于 Lucene 构建的开源分布式搜索引擎,提供了实时的搜索和数据分析能力。它广泛应用于日志分析、全文搜索、数据可视化等场景。本文将详细介绍 Elasticsearch 的安装步骤及基本操作,包括索…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
