搜索 K
Appearance
博客正在加载中...
Appearance
在计算机系统中,文件是非常重要的存储方式。Java 的标准库 java.io 提供了 File 对象来操作文件和目录。
File 对象既可以表示文件,也可以表示目录。特别要注意的是,构造一个 File 对象,即使传入的文件路径或目录路径不存在,代码也不会出错,因为构造一个 File 对象,并不会导致任何磁盘操作。只有当我们调用 File 对象的某些方法的时候,才真正进行磁盘操作(所以也要处理一些必检异常:IOException)。
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
}
}构造 File 对象的时候,可以传入相对路径和绝对路径:
C:\\Windows\\notepad.exe// 假设当前目录是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\javacFile 对象也提供了以下方法来返回路径:
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());$ pwd
D:\Projects\LearnJava\01.JavaSE\11.IO
> java IODemo1File
..
D:\Projects\LearnJava\01.JavaSE\11.IO\..
D:\Projects\LearnJava\01.JavaSE绝对路径可以表示成 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 "/"由于 Windows 平台使用 \ 作为路径分隔符,因此需要转义,用 \\ 表示一个 \。
File.pathSeparator 用来分割多个路径。当表示多个路径的时候,每个路径之间用分隔符分开,例如 windows 的环境变量,多个路径之间使用分号分隔开的。
static String pathSeparator 与系统有关的路径分隔符,String类型
static char pathSeparatorChar 与系统有关的路径分隔符,char类型其实字符串类型的分隔符,就是 char 转换的,其源码为:
//File.java
public static final String separator = "" + separatorChar;所以, 我们在写路径的时候,最好不写死分隔符(不直接写 斜杠 或者 反斜杠),可以获取分割符后拼接:
"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());运行结果
$ 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当 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!");
}有些时候,程序需要读写一些临时文件,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();当 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();执行后,文件夹目录情况:
$ tree
11.IO
└── testMkdir
├── aaa
│ └── bbb
│ ├── B.java
│ └── bbb.txt
└── aaa.txt使用 String[] list() 的输出:
String[] strs = new File("./testMkdir").list();
for (String string : strs) {
System.out.println(string);
}aaa
aaa.txt可以看到只打印了 aaa 目录和 aaa.txt,没有进入到 aaa 目录。
接下来我们试试 listFiles
File[] files = new File("./testMkdir").listFiles();
for (File f : files) {
System.out.println(f);
}输出结果:
.\testMkdir\aaa
.\testMkdir\aaa.txt如果我们加了个过滤器,只要 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);
}输出结果:
.\testMkdir\aaa.txtJava 标准库还提供了一个 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);
}
}
}Java 标准库的 java.io.File 对象表示一个文件或者目录:
File对象本身不涉及 IO 操作;getPath()/getAbsolutePath()/getCanonicalPath();isFile()/isDirectory()/ canRead() /canWrite()/ canExecute() /length()list()/listFiles();createNewFile()/ delete()需要注意的是,我们在使用流的时候,可能会发生错误,例如,文件不存在导致无法读取,没有写权限导致写入失败,等等,这些底层错误由 Java 虚拟机自动封装成 IOException 异常并抛出。因此,所有与 IO 操作相关的代码都必须正确处理 IOException(必检异常)