我们程序中的变量、数组、对象、集合都是储存在数据在内存中,计算机断电后数据会消失,如果需要持久化存储数据,需要把数据通过文件存储到硬盘。即使是存储到数据库,底层也是通过文件进行存储。因此,程序需要能操作文件。
File类是就是Java设计专门用来操作文件的类,具体来说包括文件和文件夹(目录)。准确来说,File只操作文件本身和文件夹(目录),但是不操作文件内的数据,读写文件内的数据需要通过IO流。
构造方法
File对象指代文件和文件夹,无论这个文件和文件夹是否存在。文件和文件夹,在计算机中是通过文件路径进行表达。File的实例,是映射某一个特定的文件或文件夹,因此File实例映射一个特定的文件路径。File的构造方法也说明这一点:
java
public File(String pathname);
在使用文件路径时,有绝对路径和相对路径两种方式:
- 绝对路径:完整的路径,window系统表现为从盘符开始的路径,比如
C:\user\projects\demo.txt,linux和MacOS表现为从根目录/开始的路径,比如/user/projects/demo.txt - 相对路径:相对于当前工作目录的路径,表现为文件或文件夹开头,比如
demo.txt
java
public class App {
public static void main(String[] args) {
// 使用相对路径创建File对象
File f0 = new File("file.txt");
// 使用绝对路径创建File对象(MacOS操作系统)
File f1 = new File("/Users/zhongziqiang/IdeaProjects/demo1/file.txt");
}
}
Java程序一般需要在不同计算机上运行,因此建议使用相对于项目的相对路径,这样代码迁移后无需更改代码即可运行。
由于不同操作系统的文件路径的文件层级分隔符不同,window用反斜杠\,而Linux和MacOS系统使用正斜杠/,因此,文件路径中建议使用File类静态变量separator,自动获取当前操作系统的分隔符。
java
public class App2 {
public static void main(String[] args) {
// 使用相对路径创建File对象,使用separator做分隔符
File f0 = new File("dir" + File.separator + "file.txt"); // Linux操作系统中解析为:dir/file.txt
}
}
获取基本信息的常用方法
String getName() 获取文件或目录名称,即最终的文件或者文件夹名称,不展示前面的目录层级。
java
public class App3 {
public static void main(String[] args) {
// 创建一个相对路径的File对象
File f0 = new File("dir/file.txt");
System.out.println("文件名:" + f0.getName());
// 创建一个相对路径的File对象(使用separator)
File f1 = new File("dir" + File.separator + "file.txt");
System.out.println("文件名:" + f1.getName());
// 创建一个绝对路径的File对象
File f2 = new File("/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt");
System.out.println("文件名:" + f2.getName());
}
}
无论是用相对路径还是绝对路径创建,都显示最终的文件或目录名称。
shell
文件名:file.txt
文件名:file.txt
文件名:file.txt
进程已结束,退出代码为 0
String getPath() 获取路径字符串,返回创建File对象时的路径字符串。当创建时使用的是相对路径,则会返回相对路径,若创建时使用绝对路径,则会返回绝对路径。
java
public class App4 {
public static void main(String[] args) {
// 创建一个相对路径的File对象
File f0 = new File("dir/file.txt");
System.out.println("文件名:" + f0.getPath());
// 创建一个相对路径的File对象(使用separator)
File f1 = new File("dir" + File.separator + "file.txt");
System.out.println("文件名:" + f1.getPath());
// 创建一个绝对路径的File对象
File f2 = new File("/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt");
System.out.println("文件名:" + f2.getPath());
}
}
当创建时使用的是相对路径,则会返回相对路径,若创建时使用绝对路径,则会返回绝对路径。
shell
文件名:dir/file.txt
文件名:dir/file.txt
文件名:/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt
进程已结束,退出代码为 0
String getAbsolutePath()获取文件或目录的绝对路径,当使用相对路径时创建File对象,调用该方法会返回绝对路径。
java
public class App5 {
public static void main(String[] args) {
// 创建一个相对路径的File对象
File f0 = new File("dir/file.txt");
System.out.println("文件名:" + f0.getAbsolutePath());
// 创建一个相对路径的File对象(使用separator)
File f1 = new File("dir" + File.separator + "file.txt");
System.out.println("文件名:" + f1.getAbsolutePath());
// 创建一个绝对路径的File对象
File f2 = new File("/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt");
System.out.println("文件名:" + f2.getAbsolutePath());
}
}
shell
文件名:/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt
文件名:/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt
文件名:/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt
进程已结束,退出代码为 0
使用String getParent() 获取父目录路径。
java
public class App5 {
public static void main(String[] args) {
// 创建一个相对路径的File对象
File f0 = new File("file.txt");
System.out.println("文件名:" + f0.getParent());
// 创建一个相对路径的File对象(使用separator)
File f1 = new File("dir" + File.separator + "file.txt");
System.out.println("文件名:" + f1.getParent());
// 创建一个绝对路径的File对象
File f2 = new File("/Users/zhongziqiang/IdeaProjects/demo1/dir/file.txt");
System.out.println("文件名:" + f2.getParent());
}
}
需要注意,父文件路径是返回的是创建File对象时传入的路径字符串中,最后一个分隔符之前的部分。如果创建时使用相对路径,则会展示相对路径,如果用绝对路径则会返回绝对路径。此外,若父路径不存在,则会返回null.
shell
文件名:null
文件名:dir
文件名:/Users/zhongziqiang/IdeaProjects/demo1/dir
进程已结束,退出代码为 0
使用long length()获取文件或目录大小,当文件不存在时,会返回0,当文件存在时,会返回文件的字节大小。当File对象为目录时,会返回目录的元数据大小,即文件系统中存储的对于这个目录的元数据大小,注意不是目录下存储的所有文件的大小总和。
java
public class App6 {
public static void main(String[] args) {
// 创建一个存在的File对象,是一个文件
File f0 = new File("hello.md");
System.out.println("文件大小:" + f0.length());
// 创建一个不存在的File对象
File f1 = new File("hi.md");
System.out.println("文件大小:" + f1.length());
// 创建一个存在的File对象,是一个目录
File f2 = new File("a");
System.out.println("文件大小:" + f2.length());
}
}
shell
文件大小:12
文件大小:0
文件大小:64
进程已结束,退出代码为 0
常用的判断方法
使用boolean exists()判断文件或目录是否存在
java
import java.io.File;public class App6 {
public static void main(String[] args) {
// 创建一个存在的File对象,是一个文件
File f0 = new File("hello.md");
System.out.println(f0.exists()); // true
// 创建一个不存在的File对象
File f1 = new File("hi.md");
System.out.println(f1.exists()); // false
// 创建一个存在的File对象,是一个目录
File f2 = new File("a");
System.out.println(f2.exists()); // true
}
}
使用boolean isFile() 判断是否为文件,使用boolean isDirectory()判断是否为目录。
注意:当文件或目录不存在时,无论是isFile()还是isDirectory()方法,都会返回false,所以使用这两个方法前,需要先用if分支判断文件或目录是否存在。
java
import java.io.File;public class App6 {
public static void main(String[] args) {
// 创建一个存在的File对象,是一个文件
File f0 = new File("hello.md");
System.out.println(f0.isFile()); // true
System.out.println(f0.isDirectory()); // false
// 创建一个不存在的File对象
File f1 = new File("hi.md");
System.out.println(f1.isFile()); // false 因为文件不存在
System.out.println(f1.isDirectory());// false 因为文件不存在
// 创建一个存在的File对象,是一个目录
File f2 = new File("a");
System.out.println(f2.isFile()); // false
System.out.println(f2.isDirectory()); // true
}
}
常用操作方法
使用boolean mkdir() 创建新目录。
注意,如果File对象的路径下存在文件或者目录,都无法创建新目录。此外,文件和目录并非按照"名称"来定义,文件名也可以是不带后缀的名称,比如"hello",但是不建议这么命名,因为文件名后缀是标记给操作系统用来做对应运行或者解析的标记。当然,目录也可以是带后缀的名称,比如"mydir.md",但是一般不这么命名。
java
public class App7 {
public static void main(String[] args) {
// 创建一个存在的File对象,是一个文件
File f0 = new File("hello.md");
System.out.println(f0.mkdir()); // false,因为hello.md是一个存在的文件
// 创建一个不存在的File对象
File f1 = new File("hi.md");
System.out.println(f1.mkdir()); // true,会创建一个名称为"hi.md"的目录,因为hi.md不存在
// 创建一个存在的File对象,是一个目录
File f2 = new File("a");
System.out.println(f2.mkdir()); // false,因为a是一个存在的目录
}
}
使用createNewFile()方法创建文件,同理,如果File对象的路径下存在文件或者目录,都无法创建新文件。
java
public class App7 {
public static void main(String[] args) throws IOException {
// 创建一个存在的File对象,是一个文件
File f0 = new File("hello.md");
System.out.println(f0.createNewFile()); // false,因为hello.md是一个存在的文件
// 创建一个不存在的File对象
File f1 = new File("hi.md");
System.out.println(f1.createNewFile()); // true,因为hi.md不存在
// 创建一个存在的File对象,是一个目录
File f2 = new File("a");
System.out.println(f2.createNewFile()); // false,因为a是一个存在的目录
}
}
mkdir()方法只能在前置目录都存在时创建目录,而使用boolean mkdirs() 可以创建多级目录,在前置目录不存在时,会同步创建前置的目录。
java
public class App8 {
public static void main(String[] args) {
// 创建一个不存在的File对象,dir0就不存在
File f1 = new File("dir0/dir1/dir2");
System.out.println(f1.mkdir()); // false,因为dir0不存在
// 创建一个不存在的File对象,d0就不存在
File f2 = new File("d0/d1/d2");
System.out.println(f2.mkdirs()); // true,虽然d0不存在,但是mkdir()方法会创建d0,d1,d2
}
}
使用delete() 方法删除文件或空目录。
注意:
- 删除操作不会走垃圾箱,所以无法撤回,需要谨慎操作
- 删除不存在的文件,或者非空目录会返回false,即不进行删除
java
public class App9 {
public static void main(String[] args) {
// 创建一个存在的File对象,是一个文件
File f0 = new File("hello.md");
System.out.println(f0.delete()); // true
// 创建一个不存在的File对象
File f1 = new File("hi.md");
System.out.println(f1.delete()); // false, 因为文件不存在
// 创建一个存在的File对象,是一个空目录
File f2 = new File("a");
System.out.println(f2.delete()); // true
// 创建一个存在的File对象,是一个非空目录
File f3 = new File("a");
System.out.println(f3.delete()); // false, 因为a是一个非空的目录
}
}