Skip to content

17.3 读取文本文件

读取文本文件的概念

读取文本文件是 Java IO 操作中的常见任务,它允许程序从文本文件中读取数据并进行处理。文本文件是指包含人类可读文本的文件,如 .txt、.java、.csv 等文件。

读取文本文件的方法

方法一:使用 FileReader

FileReader 是最基本的字符输入流,用于从文件中读取字符数据。

示例:使用 FileReader 读取文本文件

java
import java.io.FileReader;
import java.io.IOException;

public class ReadTextFileWithFileReader {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("example.txt")) {
            int character;
            while ((character = fr.read()) != -1) {
                System.out.print((char) character);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方法二:使用 BufferedReader

BufferedReader 是一个处理流,它包装了一个字符输入流,提供了缓冲功能和 readLine() 方法,提高读取效率。

示例:使用 BufferedReader 读取文本文件

java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadTextFileWithBufferedReader {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方法三:使用 Scanner

Scanner 类不仅可以用于读取用户输入,还可以用于读取文件内容。

示例:使用 Scanner 读取文本文件

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

public class ReadTextFileWithScanner {
    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(new File("example.txt"))) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方法四:使用 Files 类(Java 7+)

Java 7 引入了 Files 类,它提供了更简洁的方法来读取文件。

示例:使用 Files.readAllLines 读取文本文件

java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class ReadTextFileWithFiles {
    public static void main(String[] args) {
        try {
            List<String> lines = Files.readAllLines(Paths.get("example.txt"));
            for (String line : lines) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

读取文本文件的常见操作

1. 逐行读取

逐行读取是读取文本文件的常见方式,适用于处理按行组织的数据。

java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadTextFileLineByLine {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            int lineNumber = 1;
            while ((line = br.readLine()) != null) {
                System.out.println("第 " + lineNumber + " 行: " + line);
                lineNumber++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 读取特定行

有时候我们只需要读取文件中的特定行。

java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadSpecificLine {
    public static void main(String[] args) {
        int targetLine = 5; // 要读取的行号
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            int currentLine = 1;
            while ((line = br.readLine()) != null) {
                if (currentLine == targetLine) {
                    System.out.println("第 " + targetLine + " 行: " + line);
                    break;
                }
                currentLine++;
            }
            if (currentLine <= targetLine) {
                System.out.println("文件没有第 " + targetLine + " 行");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 统计文件行数

统计文件中的行数是一个常见的操作。

java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CountLines {
    public static void main(String[] args) {
        int lineCount = 0;
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            while (br.readLine() != null) {
                lineCount++;
            }
            System.out.println("文件共有 " + lineCount + " 行");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. 读取文件内容到字符串

有时候我们需要将整个文件的内容读取到一个字符串中。

java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

public class ReadFileToString {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"));
             Writer writer = new StringWriter()) {
            String line;
            while ((line = br.readLine()) != null) {
                writer.write(line);
                writer.write(System.lineSeparator());
            }
            String content = writer.toString();
            System.out.println("文件内容:\n" + content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

处理编码问题

问题描述

当读取文本文件时,可能会遇到编码问题,导致读取的内容出现乱码。

解决方案

使用 InputStreamReader 并指定正确的编码。

示例:指定编码读取文本文件

java
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class ReadTextFileWithEncoding {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream("example.txt"), StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

示例:读取 CSV 文件

CSV(Comma-Separated Values)是一种常见的文本文件格式,用于存储表格数据。

java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadCSVFile {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("data.csv"))) {
            String line;
            while ((line = br.readLine()) != null) {
                // 分割 CSV 行
                String[] fields = line.split(",");
                System.out.println("姓名: " + fields[0] + ", 年龄: " + fields[1] + ", 成绩: " + fields[2]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

常见问题

1. 文件不存在

症状:读取文件时抛出 FileNotFoundException

解决方案:确保文件路径正确,检查文件是否存在

2. 编码错误

症状:读取的内容出现乱码

解决方案:使用 InputStreamReader 并指定正确的编码

3. 内存不足

症状:读取大文件时抛出 OutOfMemoryError

解决方案:逐行读取文件,而不是一次性读取整个文件

4. 权限不足

症状:读取文件时抛出 SecurityException 或 AccessDeniedException

解决方案:确保程序有足够的权限访问文件

最佳实践

  1. 使用 try-with-resources:自动关闭流,避免资源泄漏

  2. 使用缓冲流:提高读取效率,特别是对于大文件

  3. 指定编码:处理文本文件时,指定正确的编码

  4. 逐行读取:对于大文件,使用逐行读取的方式,避免内存不足

  5. 错误处理:捕获并处理可能的异常

  6. 文件路径:使用相对路径时,注意当前工作目录

总结

读取文本文件是 Java IO 操作中的常见任务:

  1. 读取方法

    • FileReader:基本的字符输入流
    • BufferedReader:带缓冲的字符输入流,提供 readLine() 方法
    • Scanner:可以方便地读取文件内容
    • Files 类:Java 7+ 提供的简洁方法
  2. 常见操作

    • 逐行读取
    • 读取特定行
    • 统计文件行数
    • 读取文件内容到字符串
  3. 编码问题

    • 使用 InputStreamReader 并指定正确的编码
  4. CSV 文件

    • 使用 split() 方法分割 CSV 行

通过合理使用这些方法,可以有效地读取和处理文本文件,满足不同场景的需求。

© 2026 编程马·菜鸟教程 版权所有