文件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());
            }
        }
    }
}

序列化

将对象转换为字节流,可以保存到文件或网络传输。

序列化要求

示例:序列化

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 标记不参与序列化的字段。

📖 小节

📝 作业

  1. 文件统计: 统计文件中的行数、单词数、字符数
  2. 文件复制: 实现文件复制功能,支持大文件
  3. 目录遍历: 递归列出目录中所有文件,按大小排序

下一课

下一课我们将学习 流与NIO,了解Java的流式IO。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏