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

Java中使用Scanner逐行读取员工文件并存储记录的实现问题

问题分析与解决方案

你的代码存在几个关键问题,导致无法实现"逐行读取并将记录存入List"的需求:

  1. 方法参数scanner被重新赋值,外部传入的实例完全没用上;
  2. 使用StringBuilder拼接所有行,没有按行存入List;
  3. line.operator是拼写错误,正确的系统属性是line.separator,但这里其实不需要,因为scanner.nextLine()已经会读取完整一行;
  4. 缺少异常的针对性处理,且没有返回或保存读取到的记录。

以下是两种解决方案,分别对应不同的使用场景:


方案1:直接存储每行原始记录到List

适合仅需保留原始行数据的场景:

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

public class EmployeeFileHandler {
    private File employeeFile;

    public EmployeeFileHandler(File employeeFile) {
        this.employeeFile = employeeFile;
    }

    public List<String> readEmployeeRecords() {
        List<String> records = new ArrayList<>();
        
        if (!employeeFile.exists()) {
            System.err.println("文件不存在:" + employeeFile.getAbsolutePath());
            return records;
        }

        // try-with-resources自动关闭Scanner,避免资源泄漏
        try (Scanner scanner = new Scanner(employeeFile)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine().trim();
                // 跳过空行,过滤无效数据
                if (!line.isEmpty()) {
                    records.add(line);
                    System.out.printf("已读取第%d条记录:%s%n", records.size(), line);
                }
            }
        } catch (FileNotFoundException e) {
            System.err.println("无法读取文件:" + e.getMessage());
        } catch (Exception e) {
            System.err.println("读取过程中发生错误:" + e.getMessage());
        }

        return records;
    }
}

方案2:解析为自定义Employee对象(更实用)

如果需要提取员工的结构化信息,建议定义Employee类并解析每行数据:

第一步:定义Employee类

public class Employee {
    private String type; // 员工类型:D/A
    private int id;
    private String name;
    private String dob;
    private String address;
    private String employeeNumber; // D类员工专属工号
    private String statusOrPosition; // D类是状态,A类是职位

    // D类员工构造方法
    public Employee(String type, int id, String name, String dob, String address, String empNum, String status) {
        this.type = type;
        this.id = id;
        this.name = name;
        this.dob = dob;
        this.address = address;
        this.employeeNumber = empNum;
        this.statusOrPosition = status.replace("'", ""); // 去除状态字段的单引号
    }

    // A类员工构造方法(无工号字段)
    public Employee(String type, int id, String name, String dob, String address, String position) {
        this.type = type;
        this.id = id;
        this.name = name;
        this.dob = dob;
        this.address = address;
        this.statusOrPosition = position;
    }

    @Override
    public String toString() {
        return String.format("[%s] ID:%d 姓名:%s 生日:%s 地址:%s %s:%s",
                type, id, name, dob, address,
                type.equals("D") ? "工号" : "职位",
                type.equals("D") ? employeeNumber : statusOrPosition);
    }

    // 按需添加getter/setter方法
}

第二步:实现读取与解析逻辑

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

public class EmployeeFileHandler {
    private File employeeFile;

    public EmployeeFileHandler(File employeeFile) {
        this.employeeFile = employeeFile;
    }

    public List<Employee> parseEmployeeRecords() {
        List<Employee> employees = new ArrayList<>();
        
        if (!employeeFile.exists()) {
            System.err.println("文件不存在:" + employeeFile.getAbsolutePath());
            return employees;
        }

        try (Scanner scanner = new Scanner(employeeFile)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine().trim();
                if (line.isEmpty()) continue;

                // 按", "分割字段(注意逗号后有空格)
                String[] fields = line.split(", ");
                try {
                    if ("D".equals(fields[0])) {
                        // D类字段:类型, ID, 姓名, 生日, 地址, 工号, 状态
                        Employee emp = new Employee(
                                fields[0],
                                Integer.parseInt(fields[1]),
                                fields[2],
                                fields[3],
                                fields[4],
                                fields[5],
                                fields[6]
                        );
                        employees.add(emp);
                    } else if ("A".equals(fields[0])) {
                        // A类字段:类型, ID, 姓名, 生日, 地址, 职位
                        Employee emp = new Employee(
                                fields[0],
                                Integer.parseInt(fields[1]),
                                fields[2],
                                fields[3],
                                fields[4],
                                fields[5]
                        );
                        employees.add(emp);
                    }
                } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
                    System.err.println("解析行失败,跳过该行:" + line);
                }
            }
        } catch (FileNotFoundException e) {
            System.err.println("文件未找到:" + e.getMessage());
        }

        return employees;
    }

    // 测试示例
    public static void main(String[] args) {
        EmployeeFileHandler handler = new EmployeeFileHandler(new File("employees.txt"));
        List<Employee> employees = handler.parseEmployeeRecords();
        System.out.println("共解析到" + employees.size() + "条有效员工记录:");
        for (Employee emp : employees) {
            System.out.println(emp);
        }
    }
}

关键改进说明

  • 使用try-with-resources管理Scanner资源,无需手动关闭,避免资源泄漏;
  • 跳过空行,过滤无效数据;
  • 针对D/A两类员工的不同字段结构做了适配,处理了状态字段的单引号问题;
  • 捕获解析时的异常,避免单条错误记录导致整个读取流程终止;
  • 返回存储结果的List,满足需求。

内容的提问来源于stack exchange,提问作者Hải Đăng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:24:51