源本科技 | 码上会

Java 文件处理

2026/01/30
51
0

学习目标

  • 理解 Java 文件处理的核心概念与应用场景

  • 掌握 File 类的基本用法,包括文件创建、删除与信息查询

  • 区分字节流与字符流的适用场景

  • 能够完成文件的创建、写入、读取和删除等基本操作

  • 了解异常处理与资源管理的最佳实践


为什么需要文件处理

在程序运行过程中,内存中的数据是临时的,程序终止后即丢失。文件处理解决了以下关键问题:

  • 持久化存储:将数据保存到磁盘,长期保留

  • 数据共享:不同程序或系统可通过文件交换信息

  • 大数据管理:高效组织和访问大量结构化 / 非结构化数据

  • 日志记录:保存程序运行状态与错误信息

Java 通过 java.io 包提供完整的文件 I/O 支持。


File 类

文件与目录的抽象表示

File 类(位于 java.io 包)用于表示文件或目录的路径名,它不直接处理文件内容,而是提供元数据操作和文件系统交互能力。

import java.io.File;

public class FileExample {
    public static void main(String[] args) {
        // 创建 File 对象(仅表示路径,不创建实际文件)
        File file = new File("data.txt");
        System.out.println("文件路径: " + file.getAbsolutePath());
    }
}

注意:new File("name") 不会在磁盘上创建文件,仅创建一个路径引用。


I/O 流

数据读写的真正机制

虽然 File 类用于表示文件,但实际的数据读写依赖 I/O 流。Java I/O 流分为两大类:

1. 字节流

  • 处理 8 位原始字节byte

  • 适用于二进制数据:图片、音频、视频、压缩包等

  • 核心抽象类:InputStream(读)、OutputStream(写)

  • 常用实现类:

    • FileInputStream / FileOutputStream:文件字节读写

    • BufferedInputStream / BufferedOutputStream:带缓冲,提升性能

2. 字符流

  • 处理 16 位 Unicode 字符

  • 适用于文本数据,自动处理字符编码(如 UTF-8)

  • 核心抽象类:Reader(读)、Writer(写)

  • 常用实现类:

    • FileReader / FileWriter:文本文件读写

    • BufferedReader / BufferedWriter:带缓冲,支持按行读取

选择原则

  • 文本 → 字符流(FileReader / FileWriter

  • 二进制 → 字节流(FileInputStream / FileOutputStream


基础文件操作

1. 创建文件

使用 createNewFile() 方法创建新文件(若不存在):

import java.io.File;
import java.io.IOException;

public class CreateFile {
    public static void main(String[] args) {
        File file = new File("notes.txt");
        
        try {
            if (file.createNewFile()) {
                System.out.println("文件已创建: " + file.getName());
            } else {
                System.out.println("文件已存在");
            }
        } catch (IOException e) {
            System.err.println("创建文件失败: " + e.getMessage());
        }
    }
}

createNewFile() 是原子操作,可避免并发创建冲突


2. 写入文件

使用 FileWriter 向文件写入文本:

import java.io.FileWriter;
import java.io.IOException;

public class WriteFile {
    public static void main(String[] args) {
        try (FileWriter writer = new FileWriter("notes.txt")) {
            writer.write("Java 文件处理功能强大且灵活!");
            writer.write("\n这是第二行内容。");
            System.out.println("内容已成功写入文件");
        } catch (IOException e) {
            System.err.println("写入失败: " + e.getMessage());
        }
    }
}

使用 try-with-resources 自动关闭流,确保数据落盘

追加模式写入

// 第二个参数为 true 表示追加
try (FileWriter writer = new FileWriter("notes.txt", true)) {
    writer.write("\n此内容被追加到文件末尾。");
}

3. 读取文件

方式一:使用 Scanner(适合逐行读取)

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadFileWithScanner {
    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(new File("notes.txt"))) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            System.err.println("文件未找到: " + e.getMessage());
        }
    }
}

方式二:使用 BufferedReader(更高效)

import java.io.*;

public class ReadFileWithBufferedReader {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("notes.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.err.println("读取失败: " + e.getMessage());
        }
    }
}

BufferedReader 性能优于 Scanner,尤其在大文件场景


4. 删除文件

使用 delete() 方法删除文件:

import java.io.File;

public class DeleteFile {
    public static void main(String[] args) {
        File file = new File("notes.txt");
        
        if (file.delete()) {
            System.out.println("文件已删除: " + file.getName());
        } else {
            System.out.println("删除失败(文件不存在或无权限)");
        }
    }
}

注意:delete() 也可用于删除空目录


最佳实践

1. 指定字符编码

避免乱码

FileReader/FileWriter 使用系统默认编码,跨平台可能出错。推荐显式指定编码:

// 写入 UTF-8 编码文件
try (Writer writer = new OutputStreamWriter(
        new FileOutputStream("output.txt"), 
        StandardCharsets.UTF_8)) {
    writer.write("中文内容");
}

2. 检查文件属性

File file = new File("data.txt");
System.out.println("是否存在: " + file.exists());
System.out.println("是否为文件: " + file.isFile());
System.out.println("是否为目录: " + file.isDirectory());
System.out.println("文件大小: " + file.length() + " 字节");
System.out.println("最后修改时间: " + new Date(file.lastModified()));

3. 创建多级目录

File dir = new File("parent/child/grandchild");
if (dir.mkdirs()) { // mkdirs() 创建所有必要父目录
    System.out.println("目录结构已创建");
}

重点总结

  • File 类用于表示文件 / 目录路径,不处理内容

  • 实际读写依赖 I/O 流:文本用字符流,二进制用字节流

  • 四大基础操作:

    • 创建createNewFile

    • 写入FileWriter

    • 读取Scanner/BufferedReader

    • 删除delete

  • 务必使用 try-with-resources 管理流资源

  • 跨平台文本处理应显式指定编码(如 UTF-8)

  • BufferedWriter/BufferedReader 可显著提升 I/O 性能


思考题

  1. File file = new File("test.txt"); 这行代码是否会在磁盘上创建文件?为什么?

  2. 在什么情况下 file.delete() 会返回 false?列举至少三种可能原因。

  3. 如果需要频繁向日志文件追加内容,使用 FileWriter 直接写入 vs 使用 BufferedWriter 包装,性能差异有多大?为什么?