File 对象介绍
# File 对象介绍
在计算机系统中,文件是非常重要的存储方式。Java 的标准库 java.io
提供了 File
对象来操作文件和目录。
# File 对象概述
File
对象既可以表示文件,也可以表示目录。特别要注意的是,构造一个 File
对象,即使传入的文件路径或目录路径不存在,代码也不会出错,因为构造一个 File
对象,并不会导致任何磁盘操作。只有当我们调用 File
对象的某些方法的时候,才真正进行磁盘操作(所以也要处理一些必检异常:IOException
)。
# File 对象的构造方法
File(String pathname)
:通过给定的路径名字符串,来创建新的 File 实例。File(String parent, String child)
:从父路径名字符串和子路径名字符串,创建新的 File 实例。File(File parent, String child)
:根据 File 类路径名和子路径名字符串,创建新的 File 实例。
不管是哪个构造方法,要构造一个 File
对象,都需要传入文件路径:
import java.io.File;
public class IODemo1File {
public static void main(String[] args) {
File f = new File("C:\\Windows\\notepad.exe");
System.out.println(f); //C:\Windows\notepad.exe
}
}
2
3
4
5
6
7
8
构造 File 对象的时候,可以传入相对路径和绝对路径:
- 绝对路径是以根目录开头的完整路径,例如
C:\\Windows\\notepad.exe
- 如果是相对路径,则是相对当前目录的,也就是当前路径 + 相对路径就是 File 对象的绝对路径。
// 假设当前目录是C:\Docs
File f1 = new File("sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File(".\\sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File("..\\sub\\javac"); // 绝对路径是C:\sub\javac
2
3
4
File 对象也提供了以下方法来返回路径:
String getPath()
,返回构造方法传入的路径String getName()
:返回由此 File 表示的文件或目录的名称。File getAbsolutePath()
,返回绝对路径String getCanonicalPath
,它和绝对路径类似,但是返回的是规范路径
演示如下:
// show File's method about path
File f3 = new File("..");
System.out.println(f3.getPath());
System.out.println(f3.getAbsoluteFile());
System.out.println(f3.getCanonicalPath());
2
3
4
5
$ pwd
D:\Projects\LearnJava\01.JavaSE\11.IO
> java IODemo1File
..
D:\Projects\LearnJava\01.JavaSE\11.IO\..
D:\Projects\LearnJava\01.JavaSE
2
3
4
5
6
7
绝对路径可以表示成 C:\Windows\System32\..\notepad.exe
,而规范路径就是把 .
和 ..
转换成标准的绝对路径后的路径:C:\Windows\notepad.exe
。
# 分隔符
不同操作系统的分隔符是不同的。File 对象提供了不少成员变量,用来表示当前平台的分隔符。
File.separator
用来分割一个路径中的多个连续目录,在 UNIX 中表示为“/”,在 Windows 中表示为”\”。
static String separator 与系统有关的默认名称分隔符,String类型
static char separatorChar 与系统有关的默认名称分隔符,字符类型
System.out.println(File.separator); // print "\" or "/"
2
3
由于 Windows 平台使用 \
作为路径分隔符,因此需要转义,用 \\
表示一个 \
。
File.pathSeparator
用来分割多个路径。当表示多个路径的时候,每个路径之间用分隔符分开,例如 windows 的环境变量,多个路径之间使用分号分隔开的。
static String pathSeparator 与系统有关的路径分隔符,String类型
static char pathSeparatorChar 与系统有关的路径分隔符,char类型
2
其实字符串类型的分隔符,就是 char 转换的,其源码为:
//File.java
public static final String separator = "" + separatorChar;
2
所以, 我们在写路径的时候,最好不写死分隔符(不直接写 斜杠 或者 反斜杠),可以获取分割符后拼接:
"C:" + File.separator + "develop" + File.separator + "a"+ File.separator + "a.txt"
# 获取文件的信息
File 对象提供了一些方法,可以获取文件信息
isFile()
,判断该File
对象是否是一个已存在的文件isDirectory()
,判断该File
对象是否是一个已存在的目录boolean canRead()
:是否可读boolean canWrite()
:是否可写boolean canExecute()
:是否可执行。对目录而言,是否可执行表示能否列出它包含的文件和子目录。long length()
:文件字节大小
File f1 = new File("C:\\Windows");
File f2 = new File("C:\\Windows\\notepad.exe");
File f3 = new File("C:\\Windows\\nothing"); // 一个不存在的目录
System.out.println(f1.isFile());
System.out.println(f1.isDirectory());
System.out.println(f1.canRead());
System.out.println(f1.canWrite());
System.out.println(f1.canExecute());
System.out.println(f1.length());
System.out.println(f2.isFile());
System.out.println(f2.isDirectory());
System.out.println(f2.canRead());
System.out.println(f2.canWrite());
System.out.println(f2.canExecute());
System.out.println(f2.length());
System.out.println(f3.isFile());
System.out.println(f3.isDirectory());
System.out.println(f3.canRead());
System.out.println(f3.canWrite());
System.out.println(f3.canExecute());
System.out.println(f3.length());
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
运行结果
$ javac IODemo2File.java -encoding utf8
$ java IODemo2File
false
true
true
true
true
24576
true
false
true
true
true
201216
false
false
false
false
false
0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建和删除文件
当 File 对象表示一个文件时,可以通过 createNewFile()
创建一个新文件,用 delete()
删除该文件:
File file = new File("HelloFile.txt");
if(file.createNewFile()){
System.out.println("Create File Success!");
}
if(file.delete()){
System.out.println("Delete File Success!");
}
2
3
4
5
6
7
8
有些时候,程序需要读写一些临时文件,File 对象提供了 createTempFile()
来创建一个临时文件,以及 deleteOnExit()
在 JVM 退出时自动删除该文件。
File file2 = File.createTempFile("temp", ".txt"); //文件名+后缀名
System.out.println(file2.isFile()); //true
System.out.println(file2.getAbsolutePath()); //C:\Users\peterjxl\AppData\Local\Temp\temp7845722632772728214.txt
file2.deleteOnExit();
2
3
4
# 创建和遍历目录
当 File 对象表示一个目录时,我们可以使用这些方法来操作目录:
boolean mkdir()
:创建当前 File 对象表示的目录;boolean mkdirs()
:创建当前 File 对象表示的目录,并在必要时将不存在的父目录也创建出来;boolean delete()
:删除当前 File 对象表示的目录,当前目录必须为空才能删除成功。String[] list()
和listFiles()
列出目录下的文件和子目录名。但File[] listFiles()
提供了一系列重载方法,可以过滤不想要的文件和目录。
我们来演示下:
new File("./testMkdir").mkdir();
new File("./testMkdir/aaa/bbb").mkdirs();
new File("./testMkdir/aaa.txt").createNewFile();
new File("./testMkdir/aaa/bbb/bbb.txt").createNewFile();
new File("./testMkdir/aaa/bbb/B.java").createNewFile();
2
3
4
5
6
执行后,文件夹目录情况:
$ tree
11.IO
└── testMkdir
├── aaa
│ └── bbb
│ ├── B.java
│ └── bbb.txt
└── aaa.txt
2
3
4
5
6
7
8
使用 String[] list()
的输出:
String[] strs = new File("./testMkdir").list();
for (String string : strs) {
System.out.println(string);
}
2
3
4
aaa
aaa.txt
2
可以看到只打印了 aaa 目录和 aaa.txt,没有进入到 aaa 目录。
接下来我们试试 listFiles
File[] files = new File("./testMkdir").listFiles();
for (File f : files) {
System.out.println(f);
}
2
3
4
输出结果:
.\testMkdir\aaa
.\testMkdir\aaa.txt
2
如果我们加了个过滤器,只要 txt 结尾的文件:
File[] files2 = new File("./testMkdir").listFiles(new FilenameFilter() {
public boolean accept(File dir, String name){
return name.endsWith(".txt");
}
});
for (File f : files2) {
System.out.println(f);
}
2
3
4
5
6
7
8
9
输出结果:
.\testMkdir\aaa.txt
# Path 对象
Java 标准库还提供了一个 Path
对象,它位于 java.nio.file
包。Path
对象和 File
对象类似,但操作更加简单,如果需要对目录进行复杂的拼接、遍历等操作,使用 Path
对象更方便。
import java.io.*;
import java.nio.file.*;
public class Main {
public static void main(String[] args) throws IOException {
Path p1 = Paths.get(".", "project", "study"); // 构造一个Path对象
System.out.println(p1);
Path p2 = p1.toAbsolutePath(); // 转换为绝对路径
System.out.println(p2);
Path p3 = p2.normalize(); // 转换为规范路径
System.out.println(p3);
File f = p3.toFile(); // 转换为File对象
System.out.println(f);
for (Path p : Paths.get("..").toAbsolutePath()) { // 可以直接遍历Path
System.out.println(" " + p);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 小结
Java 标准库的 java.io.File
对象表示一个文件或者目录:
- 创建
File
对象本身不涉及 IO 操作; - 可以获取路径/绝对路径/规范路径:
getPath()
/getAbsolutePath()
/getCanonicalPath()
; - 可以获取文件的相关信息:
isFile()
/isDirectory()
/canRead()
/canWrite()
/canExecute()
/length()
- 可以获取目录的文件和子目录:
list()
/listFiles()
; - 可以创建或删除文件和目录。
createNewFile()
/delete()
需要注意的是,我们在使用流的时候,可能会发生错误,例如,文件不存在导致无法读取,没有写权限导致写入失败,等等,这些底层错误由 Java 虚拟机自动封装成 IOException
异常并抛出。因此,所有与 IO 操作相关的代码都必须正确处理 IOException
(必检异常)