You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中BufferedReader的Readline()读取文件返回null问题求助

问题排查与代码修正:BufferedReader读取空文件及学生管理功能实现

首先来说你遇到的BufferedReader.readLine()始终返回null的核心原因:你在代码一开始就创建了BufferedWriter指向目标文件,默认的FileWriter构造方法会直接清空文件内容,这就导致后面用BufferedReader读取的时候,文件已经是空的了,自然返回null。除此之外,代码还有不少逻辑和功能上的问题,我帮你逐一修正:

主要问题梳理与修正点

  • 文件操作顺序颠倒:应该先读取原文件的学生数据到集合,再进行添加新学生的操作,最后统一把集合内容写入文件覆盖原内容,而不是先写再读。
  • Student类构造方法未初始化成员变量:你的Student构造方法里只打印了"s",没有把传入的name和id赋值给成员变量,导致后续所有学生对象的属性都是默认值,无法正确存储和展示。
  • 缺少学号唯一性检查:添加新学生时,需要遍历已有的studentList,检查新学号是否已经存在,确保唯一性。
  • 边添加边写入文件的逻辑错误:应该等用户完成所有添加操作后,再把整个集合的内容一次性写入文件,覆盖原数据,而不是每添加一个就写一次。
  • 缺少用户选择显示学生列表的功能:需要添加菜单选项,让用户选择显示完整学生信息还是仅学号。
  • 资源关闭不规范:应该使用try-with-resources语法自动关闭IO资源,避免手动关闭时遗漏或出错。

修正后的完整代码

import java.util.*;
import java.io.*;

public class TestStudent {
    public static void main(String[] args) {
        // 定义文件路径
        String filePath = "C:\\Users\\user1\\Desktop\\Students.txt";
        ArrayList<Student> studentList = new ArrayList<>();
        Scanner sc = new Scanner(System.in);

        // 第一步:读取原文件中的学生数据到集合
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] record = line.split("\t");
                // 确保每行数据格式正确(姓名+学号)
                if (record.length == 2) {
                    Student student = new Student(record[0], record[1]);
                    studentList.add(student);
                }
            }
        } catch (FileNotFoundException e) {
            // 如果文件不存在,说明是第一次使用,直接创建空集合即可
            System.out.println("未找到学生文件,将创建新文件");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 第二步:允许用户添加新学生,检查学号唯一性
        String cont;
        do {
            System.out.println("请输入学生姓名:");
            String name = sc.next();
            String id;
            // 循环直到输入有效的唯一学号
            while (true) {
                System.out.println("请输入6位数字学号:");
                id = sc.next();
                Student tempStudent = new Student(name, id);
                // 检查学号格式是否有效
                if (!tempStudent.isValidID()) {
                    System.out.println("学号格式错误!必须是6位数字,请重新输入");
                    continue;
                }
                // 检查学号是否已存在
                boolean idExists = false;
                for (Student s : studentList) {
                    if (s.getId().equals(id)) {
                        idExists = true;
                        break;
                    }
                }
                if (idExists) {
                    System.out.println("该学号已存在,请重新输入");
                } else {
                    break;
                }
            }
            // 添加合法的新学生到集合
            studentList.add(new Student(name, id));
            System.out.println("是否继续添加学生?(y/n)");
            cont = sc.next();
        } while (cont.equalsIgnoreCase("y"));

        // 第三步:将集合中的所有学生数据覆盖写入文件
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
            for (Student s : studentList) {
                bw.write(s.getName() + "\t" + s.getId());
                bw.newLine();
            }
            System.out.println("学生数据已成功保存到文件");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 第四步:提供显示选项
        System.out.println("请选择显示方式:");
        System.out.println("1. 显示完整学生列表");
        System.out.println("2. 仅显示学生学号");
        int choice = sc.nextInt();
        switch (choice) {
            case 1:
                System.out.println("完整学生列表:");
                for (Student s : studentList) {
                    System.out.println(s.toString());
                }
                break;
            case 2:
                System.out.println("学生学号列表:");
                for (Student s : studentList) {
                    System.out.println(s.getId());
                }
                break;
            default:
                System.out.println("无效选项,退出显示");
        }

        sc.close();
    }
}

class Student {
    private String name;
    private String id;

    // 修正构造方法,正确初始化成员变量
    public Student(String name, String id) {
        this.name = name;
        this.id = id;
    }

    // Getter方法
    public String getName() {
        return this.name;
    }

    public String getId() {
        return this.id;
    }

    // Setter方法
    public void setName(String name) {
        this.name = name;
    }

    public void setId(String id) {
        this.id = id;
    }

    // 重写toString方法,返回清晰的学生信息
    @Override
    public String toString() {
        return "学生姓名:" + getName() + ",学号:" + getId();
    }

    // 检查学号是否为6位数字
    public boolean isValidID() {
        if (id.length() != 6) {
            return false;
        }
        for (char c : id.toCharArray()) {
            if (!Character.isDigit(c)) {
                return false;
            }
        }
        return true;
    }
}

代码说明

  1. 文件读取逻辑:先用BufferedReader读取原文件内容到集合,如果文件不存在则捕获FileNotFoundException,提示用户将创建新文件。
  2. 学号验证:添加学生时先检查学号格式(6位数字),再遍历集合检查学号是否已存在,确保唯一性。
  3. 文件写入逻辑:用户完成添加后,用BufferedWriter将整个集合的内容一次性写入文件,覆盖原数据。
  4. 显示功能:提供菜单选项,让用户选择显示完整信息或仅学号。
  5. 资源管理:使用try-with-resources自动关闭IO流,避免资源泄漏。

内容的提问来源于stack exchange,提问作者Maizere Pathak.Nepal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:01:57