Java 8 Stream – 逐行读取文件

更新于 2025-12-27

在 Java 8 中,你可以使用 Files.lines 将文件作为 Stream(流)来读取。

c://lines.txt – 用于测试的简单文本文件:

line1
line2
line3
line4
line5

1. Java 8 读取文件 + Stream

TestReadFile.java

package com.mkyong.java8;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class TestReadFile {

    public static void main(String args[]) {

        String fileName = "c://lines.txt";

        // 将文件读入流中,使用 try-with-resources
        try (Stream<String> stream = Files.lines(Paths.get(fileName))) {

            stream.forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

输出:

line1
line2
line3
line4
line5

2. Java 8 读取文件 + Stream + 高级操作

此示例展示了如何使用 Stream 过滤内容、将所有内容转换为大写,并将其收集为一个 List

TestReadFile2.java

package com.mkyong.java8;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestReadFile2 {

    public static void main(String args[]) {

        String fileName = "c://lines.txt";
        List<String> list = new ArrayList<>();

        try (Stream<String> stream = Files.lines(Paths.get(fileName))) {

            // 1. 过滤掉以 "line3" 开头的行
            // 2. 将所有内容转换为大写
            // 3. 收集为 List
            list = stream
                    .filter(line -> !line.startsWith("line3"))
                    .map(String::toUpperCase)
                    .collect(Collectors.toList());

        } catch (IOException e) {
            e.printStackTrace();
        }

        list.forEach(System.out::println);

    }

}

输出:

LINE1
LINE2
LINE4
LINE5

3. BufferedReader + Stream

从 Java 1.8 开始,BufferedReader 新增了一个 lines() 方法,可以将内容以 Stream 的形式返回。

TestReadFile3.java

package com.mkyong.java8;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class TestReadFile3 {

    public static void main(String args[]) {

        String fileName = "c://lines.txt";
        List<String> list = new ArrayList<>();

        try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName))) {

            // br 返回一个 Stream,并将其收集为 List
            list = br.lines().collect(Collectors.toList());

        } catch (IOException e) {
            e.printStackTrace();
        }

        list.forEach(System.out::println);

    }

}

输出:

line1
line2
line3
line4
line5

4. 传统的 BufferedReader 和 Scanner 方式

Java 8 和 Stream 虽然强大,但让我们回顾一下传统的 BufferedReader(JDK 1.1 引入)和 Scanner(JDK 1.5 引入)方式。这些方法仍然有效,只是开发者现在更倾向于使用 Stream。

4.1 使用 try-with-resources 的 BufferedReader 示例

TestReadFile4.java

package com.mkyong.core;

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

public class TestReadFile4 {

    public static void main(String args[]) {

        String fileName = "c://lines.txt";

        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {

            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

4.2 使用 try-with-resources 的 Scanner 示例

TestReadFile5.java

package com.mkyong.core;

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

public class TestReadFile5 {

    public static void main(String args[]) {

        String fileName = "c://lines.txt";

        try (Scanner scanner = new Scanner(new File(fileName))) {

            while (scanner.hasNext()) {
                System.out.println(scanner.nextLine());
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}