文件IO
文件操作是程序的重要功能,本课学习Java中的文件IO。
File类
File类用于操作文件和目录。
创建File对象
JAVA
import java.io.File;
// 方式1:路径字符串
File file1 = new File("test.txt");
// 方式2:父路径+文件名
File file2 = new File("/home/user", "test.txt");
// 方式3:File对象+文件名
File dir = new File("/home/user");
File file3 = new File(dir, "test.txt");
常用方法
| 方法 | 说明 |
|---|---|
exists() |
是否存在 |
isFile() |
是否是文件 |
isDirectory() |
是否是目录 |
getName() |
获取文件名 |
getPath() |
获取路径 |
getAbsolutePath() |
获取绝对路径 |
length() |
文件大小(字节) |
createNewFile() |
创建文件 |
mkdir() |
创建目录 |
mkdirs() |
创建多级目录 |
delete() |
删除 |
list() |
列出目录内容 |
示例:File操作
JAVA
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
File file = new File("test.txt");
// 创建文件
if (!file.exists()) {
file.createNewFile();
System.out.println("文件创建成功");
}
// 文件信息
System.out.println("文件名:" + file.getName());
System.out.println("路径:" + file.getPath());
System.out.println("绝对路径:" + file.getAbsolutePath());
System.out.println("大小:" + file.length() + "字节");
System.out.println("是否是文件:" + file.isFile());
System.out.println("是否是目录:" + file.isDirectory());
// 删除文件
// file.delete();
}
}
示例:目录操作
JAVA
import java.io.File;
public class DirectoryDemo {
public static void main(String[] args) {
// 创建目录
File dir = new File("testdir/subdir");
dir.mkdirs();
System.out.println("目录创建成功:" + dir.getAbsolutePath());
// 列出目录内容
File parent = new File("testdir");
String[] files = parent.list();
if (files != null) {
for (String name : files) {
System.out.println(" " + name);
}
}
// 遍历目录
File[] fileArray = parent.listFiles();
if (fileArray != null) {
for (File f : fileArray) {
String type = f.isDirectory() ? "[目录]" : "[文件]";
System.out.println(type + " " + f.getName());
}
}
}
}
文件读写
BufferedReader读取文件
JAVA
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String[] args) {
// try-with-resources自动关闭资源
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("读取失败:" + e.getMessage());
}
}
}
BufferedWriter写入文件
JAVA
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class WriteFile {
public static void main(String[] args) {
// 覆盖写入
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("Hello, World!");
writer.newLine();
writer.write("Java文件操作");
System.out.println("写入成功");
} catch (IOException e) {
System.out.println("写入失败:" + e.getMessage());
}
// 追加写入
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt", true))) {
writer.write("追加内容");
writer.newLine();
System.out.println("追加成功");
} catch (IOException e) {
System.out.println("追加失败:" + e.getMessage());
}
}
}
try-with-resources
Java 7引入,自动关闭实现了AutoCloseable接口的资源。
语法
JAVA
try (资源类型 变量 = new 资源()) {
// 使用资源
} catch (异常类型 e) {
// 处理异常
}
示例:文件复制
JAVA
import java.io.*;
public class FileCopy {
public static void copy(String src, String dest) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(src));
BufferedWriter writer = new BufferedWriter(new FileWriter(dest))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
}
System.out.println("复制完成");
}
public static void main(String[] args) {
try {
copy("source.txt", "dest.txt");
} catch (IOException e) {
System.out.println("复制失败:" + e.getMessage());
}
}
}
读取所有内容
方式1:逐行读取
JAVA
public static String readAll(String filename) throws IOException {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
}
return sb.toString();
}
方式2:Files工具类(Java 7+)
JAVA
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.List;
public class FilesDemo {
public static void main(String[] args) throws IOException {
// 读取所有行
List<String> lines = Files.readAllLines(Paths.get("test.txt"));
lines.forEach(System.out::println);
// 读取为字符串
String content = new String(Files.readAllBytes(Paths.get("test.txt")));
System.out.println(content);
// 写入文件
Files.write(Paths.get("output.txt"), "Hello".getBytes());
}
}
文件遍历
递归遍历目录
JAVA
import java.io.File;
public class ListFiles {
public static void listFiles(File dir, String indent) {
File[] files = dir.listFiles();
if (files == null) return;
for (File file : files) {
System.out.println(indent + file.getName());
if (file.isDirectory()) {
listFiles(file, indent + " ");
}
}
}
public static void main(String[] args) {
File dir = new File(".");
listFiles(dir, "");
}
}
文件过滤
JAVA
import java.io.File;
import java.io.FilenameFilter;
public class FileFilter {
public static void main(String[] args) {
File dir = new File(".");
// 只列出.txt文件
String[] txtFiles = dir.list((d, name) -> name.endsWith(".txt"));
if (txtFiles != null) {
for (String name : txtFiles) {
System.out.println(name);
}
}
// 只列出目录
File[] dirs = dir.listFiles(File::isDirectory);
if (dirs != null) {
for (File d : dirs) {
System.out.println("[目录] " + d.getName());
}
}
}
}
序列化
将对象转换为字节流,可以保存到文件或网络传输。
序列化要求
- 类实现
Serializable接口 - 所有字段也必须可序列化
示例:序列化
JAVA
import java.io.*;
// 可序列化的类
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private transient String password; // transient不参与序列化
public User(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + ", password='" + password + "'}";
}
}
public class SerializeDemo {
public static void main(String[] args) {
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
User user = new User("Alice", 25, "123456");
oos.writeObject(user);
System.out.println("序列化成功");
} catch (IOException e) {
System.out.println("序列化失败:" + e.getMessage());
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
User user = (User) ois.readObject();
System.out.println("反序列化:" + user);
// User{name='Alice', age=25, password='null'}(password被忽略)
} catch (IOException | ClassNotFoundException e) {
System.out.println("反序列化失败:" + e.getMessage());
}
}
}
❓ 常见问题
Q 相对路径和绝对路径有什么区别?
A 相对路径相对于当前工作目录,绝对路径从根目录开始。
Q 为什么用try-with-resources?
A 自动关闭资源,避免资源泄漏。比手动finally更简洁。
Q transient关键字是什么作用?
A 标记不参与序列化的字段。
📖 小节
- File类操作文件和目录
- BufferedReader/BufferedWriter读写文件
- try-with-resources自动关闭资源
- Files工具类简化文件操作
- 序列化将对象保存到文件
📝 作业
- 文件统计: 统计文件中的行数、单词数、字符数
- 文件复制: 实现文件复制功能,支持大文件
- 目录遍历: 递归列出目录中所有文件,按大小排序
下一课
下一课我们将学习 流与NIO,了解Java的流式IO。



