Java 中通过 java.io.File
类来对文件进行描述。
构造方法 | 说明 |
---|---|
File(String pathname) |
通过路径名字符串来创建 File 实例 |
File(String parent, String child) |
从父路径名字符串和子路径名字符串创建 File 实例 |
File(File parent, String child) |
从父抽象路径名和子路径名字符串创建 File 实例 |
注意:创建 File 实例不等于创建文件
方法 | 说明 |
---|---|
String getParent() |
返回父路径名字符串 |
String getName() |
返回该抽象路径名表示的文件或目录的名称 |
String getPath() |
将此抽象路径名转换为路径名字符串 |
String getAbsolutePath() |
返回此抽象路径名的绝对路径名字符串 |
String getCanonicalPath() |
返回此抽象路径名的规范路径名字符串 |
boolean exists() |
测试此抽象路径名表示的文件或目录是否存在 |
boolean isDirectory() |
测试此抽象路径名表示的文件是否为目录 |
boolean isFile() |
测试此抽象路径名表示的文件是否为普通文件 |
boolean createNewFile() |
当且仅当具有此名称的文件还不存在时,原子地创建一个由该抽象路径名命名的新的空文件。 |
boolean delete() |
删除由该抽象路径名表示的文件或目录 |
void deleteOnExit() |
请求在虚拟机终止时删除由该抽象路径名表示的文件或目录 |
String[] list() |
返回该抽象路径名下的文件名 |
File[] listFiles() |
返回一个抽象路径名数组,表示该抽象路径名所表示的目录中的文件 |
boolean mkdir() |
创建以此抽象路径名命名的目录 |
boolean mkdirs() |
创建以此抽象路径名命名的目录,如果必要,会创建中间目录 |
boolean renameTo(File dest) |
重命名由该抽象路径名表示的文件 |
boolean canRead() |
测试应用程序是否可以读取由该抽象路径名表示的文件 |
boolean canWrite() |
测试应用程序是否可以修改由该抽象路径名表示的文件 |
示例:
public static void main(String[] args) throws IOException {
File file = new File("d:/test.txt");
System.out.println(file.getParent()); // d:\
System.out.println(file.getName()); // test.txt
System.out.println(file.getPath()); // d:\test.txt
System.out.println(file.getAbsolutePath()); // d:\test.txt
System.out.println(file.getCanonicalPath()); // D:\test.txt
}
public static void main(String[] args) throws IOException {
File file = new File("helloworld.txt");
System.out.println(file.exists()); // false
System.out.println(file.isDirectory()); // false
System.out.println(file.isFile()); // false
System.out.println("=============================");
// 创建文件
file.createNewFile();
System.out.println(file.exists()); // true
System.out.println(file.isDirectory()); // false
System.out.println(file.isFile()); // true
}
public static void main(String[] args) {
File file = new File("helloworld.txt");
// 删除文件
file.delete();
System.out.println(file.exists()); // false
}
public static void main(String[] args) throws IOException, InterruptedException {
File file = new File("helloworld.txt");
// 把文件创建回来
file.createNewFile();
// 在程序退出前删除
file.deleteOnExit();
Thread.sleep(5000);
System.out.println(file.exists()); // true
}
public static void main(String[] args) {
// 创建目录
File file = new File("test");
System.out.println(file.exists()); // false
System.out.println(file.isDirectory()); // false
System.out.println("========================");
file.mkdir();
System.out.println(file.exists()); // true
System.out.println(file.isDirectory()); // true
}
public static void main(String[] args) {
// 创建多级目录
File file = new File("test/a/b/c");
System.out.println(file.exists()); // false
System.out.println(file.isDirectory()); // false
System.out.println("========================");
file.mkdirs();
System.out.println(file.exists()); // true
System.out.println(file.isDirectory()); // true
}
public static void main(String[] args) throws IOException {
// 文件重命名
File file1 = new File("test1.txt");
File file2 = new File("test2.txt");
file1.createNewFile(); // 创建 test1.txt
file1.renameTo(file2); // 重命名成 test2.txt
}
相关的类:
InputStream
OutputStream
,用于操作二进制文件Reader
Writer
,用于操作文本文件方法 | 说明 |
---|---|
int read() |
从输入流中读取下一个字节的数据。值字节以 int 形式返回,其范围为 0 到 255。如果由于到达流的末尾而没有可用的字节,则返回值 -1。此方法会阻塞,直到输入数据可用、检测到流的末尾或引发异常为止。 |
int read(byte b[]) |
从输入流中读取一定数量的字节,并将其存储到数组 b 中,并且尽可能把 b 填满。实际读取的字节数以整数形式返回。此方法会阻塞,直到输入数据可用、检测到文件结尾或引发异常为止。 |
int read(byte b[], int off, int len) |
也是把读到的字节往 b 里塞,从 off 的位置开始塞,最多塞 len 个字节 |
InputStream
是一个抽象类,通过 new 它的子类 FileInputStream
来实例化
// 文件内容:hello
public static void main(String[] args) throws IOException {
// 打开文件
InputStream inputStream = new FileInputStream("test2.txt");
// 读取文件
while (true) {
int b = inputStream.read();
if (b == -1) {
break;
}
System.out.println(b);
}
// 关闭文件
inputStream.close();
}
/*输出:
104
101
108
108
111
*/
这正是 hello 的 ASCII 码
要想把字节流还原成原来的文本,需要手动处理:
public static void main(String[] args) throws IOException {
// 打开文件
InputStream inputStream = new FileInputStream("test2.txt");
// 读取文件
byte[] b = new byte[1024];
int len = inputStream.read(b);
// 还原成文本
String s = new String(b, 0, len, StandardCharsets.UTF_8);
System.out.println(s);
// 关闭文件
inputStream.close();
}
方法 | 说明 |
---|---|
int read(java.nio.CharBuffer target) |
尝试将字符读取到指定的字符缓冲区中 |
int read() |
读取单个字符。此方法将阻塞,直到字符可用、发生I/O错误或到达流的末尾 |
int read(char cbuf[]) |
将字符读取到数组中。此方法将一直阻塞,直到某个输入可用、出现I/O错误或到达流的末尾 |
int read(char cbuf[], int off, int len) |
将字符读入数组的一部分。此方法将一直阻塞,直到某个输入可用、出现I/O错误或到达流的末尾 |
使用 FileReader
实例化
例:Reader 直接读取到文本
public static void main(String[] args) throws IOException {
Reader reader = new FileReader("test2.txt");
char[] buffer = new char[1024];
int len = reader.read(buffer);
for (int i = 0; i < len; ++i) {
System.out.println(buffer[i]);
}
reader.close();
}
其实读文件最方便的写法,是使用 Scanner:
这个我们在标准输入的时候用过,只要把 System.in
换成其他 InputStream
public static void main(String[] args) throws IOException {
InputStream inputStream = new FileInputStream("test2.txt");
Scanner scanner = new Scanner(inputStream);
String s = scanner.next();
System.out.println(s);
inputStream.close();
}
技巧:使用 try with resources 关闭文件
try (InputStream inputStream = new FileInputStream("test2.txt")){
// ......
} catch (IOException e) {
e.printStackTrace();
}
方法 | 说明 |
---|---|
void write(int b) |
将指定的字节写入此输出流 |
void write(byte b[]) |
将指定字节数组中的 b.length 个字节写入此输出流 |
void write(byte b[], int off, int len) |
从偏移量为 off 的指定字节数组中写入 len 个字节到此输出流 |
public static void main(String[] args) throws IOException {
try (OutputStream outputStream = new FileOutputStream("test2.txt")) {
outputStream.write('a');
outputStream.write('b');
outputStream.write('c');
}
}
如果要输出一个字符串,那么需要转为字节数组:
public static void main(String[] args) throws IOException {
try (OutputStream outputStream = new FileOutputStream("test2.txt")) {
String s = "你好";
outputStream.write(s.getBytes());
}
}
注意:打开文件会清空文件内容,写的时候并不会
方法 | 说明 |
---|---|
void write(int c) |
写入单个字符 |
void write(char cbuf[]) |
写入一个字符数组 |
void write(char cbuf[], int off, int len) |
写入字符数组的一部分 |
void write(String str) |
写入字符串 |
void write(String str, int off, int len) |
写入字符串的一部分 |
public static void main(String[] args) throws IOException {
try (Writer writer = new FileWriter("test2.txt")) {
writer.write("hello world");
}
}
使用 PrintWriter 包装一下:
public static void main(String[] args) throws IOException {
try (OutputStream outputStream = new FileOutputStream("test2.txt")) {
PrintWriter printWriter = new PrintWriter(outputStream);
// 此处 printWriter 的用法就和 System.out 类似了
printWriter.println("aaa");
printWriter.flush();
}
}
注意:PrintWriter
自带缓冲区,如果你写的内容太短,可能需要 flush
一下
递归查找目录下的所有文件,将文件名包含指定字符串的文件删除
import java.io.*;
import java.util.Scanner;
public class demo {
public static void main(String[] args) throws IOException {
System.out.println("请输入要扫描的路径:");
Scanner scanner = new Scanner(System.in);
String rootPath = scanner.next();
File root = new File(rootPath);
if (!root.exists()) {
System.out.println("输入的路径不存在");
return;
}
System.out.println("请输入要删除的文件名(或部分):");
String toDelete = scanner.next();
// 递归删除文件
scanDir(root, toDelete);
}
public static void scanDir(File rootDir, String toDelete) throws IOException {
File[] files = rootDir.listFiles();
if (files == null) {
return;
}
for (File f : files) {
if (f.isDirectory()) {
scanDir(f, toDelete);
} else {
tryDelete(f, toDelete);
}
}
}
public static void tryDelete(File f, String toDelete) throws IOException {
if (f.getName().contains(toDelete)) {
System.out.println("是否删除文件(y/n):" + f.getCanonicalPath());
Scanner scanner = new Scanner(System.in);
String choice = scanner.next();
if (choice.equals("y")) {
f.delete();
}
}
}
}
import java.io.*;
import java.util.Scanner;
public class demo {
public static void main(String[] args) throws IOException {
System.out.println("请输入要复制的文件路径:");
Scanner scanner = new Scanner(System.in);
String srcPath = scanner.next();
File srcFile = new File(srcPath);
if (!srcFile.exists()) {
System.out.println("文件不存在");
return;
}
if (!srcFile.isFile()) {
System.out.println("不是普通文件");
return;
}
System.out.println("请输入目标路径:");
String destPath = scanner.next();
File destFile = new File(destPath);
if (destFile.exists()) {
System.out.println("目标已经存在");
return;
}
// 开始复制
try (InputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(destFile)) {
byte[] buf = new byte[1024];
while (true) {
int len = inputStream.read(buf);
if (len == -1) {
// 拷贝完成
break;
}
outputStream.write(buf, 0, len);
}
}
System.out.println("复制完成");
}
}