认识文件操作与IO
文章目录
认识文件
我们平时所说的文件指的是存在硬盘上的文件,我们平时的重要数据内容都以文件的方式来存储,我们平时书写的Java代码实际上是操作内存的一种方式,通过在内存上申请空间去执行操作。
我们接下来学习通过对文件以及IO接口的操作来实现对硬盘的操作,他能更直接的操作我们平时用到的数据文件,无论在我们的工作还是在我们的学习中,这都是不可或缺的。
文件夹
我们通俗的将目录文件称为文件夹,文件如同数据一般,我们计算机也通过管理数据的方式来管理文件
可以看到,计算机是通过树状结构来管理文件目录
文件路径
我们所说的路径就是找到文件途经的目录组成的,根据树状结构,我们知道找到一个文件就是从根开始,一路沿着树杈走下去所经过的目录,Windows系统都是通过此电脑起手的,所以我们通常省略此电脑
- 绝对路径:指的是一个具体的路径,以盘符开头的。比如:C:\Program Files\Java\text
- 相对路径:指的是从给定目录出发寻找文件(.开头)。比如:.\text
注:Windows上文件与路径一一对应
文件分类
文件通常被分为文本文件
与二进制文件
- 文本文件:存储的是字符
- 二进制文件:存储二进制数据
我们可以通过记事本1打开,出现乱码则是二进制文件
文件操作
主要指通过文件资源管理器能够完成的一些功能,在Java中提供了File类
,通过这个类来完成一系列操作,下面我们进入正题。
File类
File类存在java.io
包中
构造方法
File(String pathname) //根据文件路径创建一个新的File 实例
注:此处的文件可以不存在,只要目录可以找到,调用createNewFile()就可以创建该文件
常用方法
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
String | getParent() | 返回 File |
String | getName() | 返回 FIle 对象的纯文件名称 |
String | getPath() | 返回 File 对象的文件路径 |
String | getAbsolutePath() | 返回 File 对象的绝对路径 |
String | getCanonicalPath() | 返回 File 对象的修饰过的绝对路径 |
boolean | exists() | 判断 File 对象描述的文件是否真实存在 |
boolean | isDirectory() | 判断 File 对象代表的文件是否是一个目录 |
boolean | isFile() | 判断 File 对象代表的文件是否是一个普通文件 |
boolean | createNewFile() | 根据 File 对象,自动创建一个空文件。成功创建后返回 true |
boolean | delete() | 根据 File 对象,删除该文件。成功删除后返回 true |
void | deleteOnExit() | 根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行 |
String[] | list() | 返回 File 对象代表的目录下的所有文件名 |
File[] | listFiles() | 返回 File 对象代表的目录下的所有文件,以 File 对象表示 |
boolean | mkdir() | 创建 File 对象代表的目录 |
boolean | mkdirs() | 创建 File 对象代表的目录,如果必要,会创建中间目录 |
boolean | renameTo(Filedest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操作 |
boolean | canRead() | 判断用户是否对文件有可读权限 |
boolean | canWrite() | 判断用户是否对文件有可写权限 |
以上操作都较为简单,只需注意在IDEA的工作目录是当前项目所在的目录.\代表当前工作目录(基准目录). .\代表当前工作目录的父目录
字节流IO
每种流对象都分为两种,输入与输出,输入是指将硬盘数据送到CPU,输出是指将数据从CPU送到硬盘,也就是说我们讨论的输入输出是以CPU为基准的
InputStream
关于InputStream类,Java中实现的方法是抽象类,因此我们不能够直接实例化,而是通常使用实现了这个抽象类的类,就目前阶段,我们不涉及到网络等等内容,只关心从文件中读取,所以使用FileInputStream
常用方法
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
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() | 关闭字节流 |
注:关闭操作是非常必要的,不同于Java之前的习惯,文件这里的资源需要手动释放
!!!
FileInputStream
构造方法
签名 | 说明 |
---|---|
FileInputStream(File file) | 利用 File 构造文件输入流 |
FileInputStream(String name) | 利用文件路径构造文件输入流 |
FileInputStream实例
InputStream inputStream = new FileInputStream("D:/J-student-s:/JE-student-23-7-9");
一种优秀的书写习惯(try with resources):
try(InputStream inputStream = new FileInputStream("D:/J-student-s:/JE-student-23-7-9")){
//这种写法可以自动释放资源
}
前面InputStream中提供了三种read版本,返回值-1代表读取结束,我们写如下读文件操作:
import java.io.*;
public class Text1 {
public static void main(String[] args) throws IOException {
try(InputStream inputStream = new FileInputStream("D:\\student-Java-s\\JE-student-23-7-9\\text.txt");){
while(true){
int b = inputStream.read();
if (b==-1){
break;
}
System.out.print(b);
System.out.printf("%c\n",b);
}
}
}
}
运行结果如下:
OutputStream
方法
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
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(刷新)操作,将数据刷到设备中。 |
注:同样的,我们使用FileOutputStream
来写入文件
FileOutputStream
这里不过多叙述,具体构造方法以及使用与FileInputStream相同
字符流IO
主要使用抽象类reader、writer,实例类FileReader、FileWriter,用read、writer来写与读,与字节流完全一样,仅有的区别是字符流IO一次读一个字符,字节流一次读一个字节,这里就不再啰嗦了~