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

为何读取文本文件并正常打印时仍抛出NoSuchElementException?

解决CSV读取时的NoSuchElementException异常

我能读取文本文件的所有内容并打印数据,但仍会抛出NoSuchElementException异常。尝试了在while循环中使用hasNext()的方案,但没起作用。

原实现代码

public void fileReader() throws IOException {
    String id;
    String brand;
    int yearOfManufacture;
    int numSeats;
    double rentalPerDay;
    double insurancePerDay;
    double serviceFee;
    double discount;
    String model;
    String type;
    String color;
    ArrayList<Vehicle> vehicleArray = new ArrayList<>();
    File file = new File("C:/Users/jockg/Downloads/Fleet (1).csv");
    Scanner scan = new Scanner(file);
    scan.useDelimiter("n/n");

    while (scan.hasNext() || scan.hasNextDouble() || scan.hasNextInt()) {

        id = scan.next();
         System.out.println(id);
        brand = scan.next();
         System.out.println(brand);
        model = scan.next();
         System.out.println(model);
        type = scan.next();
         System.out.println(type);
        yearOfManufacture = Integer.parseInt(scan.next());
         System.out.println(yearOfManufacture);
        numSeats = Integer.parseInt(scan.next());
         System.out.println(numSeats);
        color = scan.next();
         System.out.println(color);
        rentalPerDay = Double.parseDouble(scan.next());
         System.out.println(rentalPerDay);
        insurancePerDay = Double.parseDouble(scan.next());
         System.out.println(insurancePerDay);
        serviceFee = Double.parseDouble(scan.next());
         System.out.println(serviceFee);
        if (scan.next().equals("N/A")) {
            discount = 0;
        } else {
            discount = Double.parseDouble(scan.next());
        }

         System.out.println(discount);

        Car newCar = new Car(id, brand, yearOfManufacture, numSeats, rentalPerDay, insurancePerDay, serviceFee,
                discount, model, type, color);
        vehicleArray.add(newCar);
    }
}

CSV文件内容

C001,Toyota,Yaris,Sedan,2012,4,Blue,50,15,10,10
C002,Toyota,Corolla,Hatch,2020,4,White,45,20,10,10
C003,Toyota,Kluger,SUV,2019,7,Grey,70,20,20,10
C004,Audi,A3,Sedan,2015,5,Red,65,10,20,10
C005,Holden,Cruze,Hatch,2020,4,Green,70,10,10,10
C006,BMW,X5,SUV,2018,7,White,100,25,20,10
C007,BMW,320i,Sedan,2021,5,Grey,75,10,15,N/A
C008,Ford,Focus,Sedan,2014,5,Red,45,10,10,N/A
C009,Ford,Puma,SUV,2015,5,Black,70,20,15,20

问题分析

  1. 分隔符设置错误:scan.useDelimiter("n/n")完全不符合CSV格式,CSV用逗号分隔字段、每行是一条完整记录,错误的分隔符会导致Scanner读取逻辑混乱。
  2. 循环条件逻辑错误:scan.hasNext() || scan.hasNextDouble() || scan.hasNextInt()使用逻辑或,只要任意一个条件为真就会继续循环,即使后续已经没有可读取的元素,最终触发NoSuchElementException。
  3. 重复读取元素:处理discount时,if (scan.next().equals("N/A"))调用了一次scan.next(),如果条件不成立,又会调用一次scan.next(),导致跳过一个字段,后续读取全部错位,最终无元素可读时抛出异常。

修正后的代码

public void fileReader() throws IOException {
    ArrayList<Vehicle> vehicleArray = new ArrayList<>();
    File file = new File("C:/Users/jockg/Downloads/Fleet (1).csv");
    Scanner scan = new Scanner(file);

    // 逐行读取每条车辆记录
    while (scan.hasNextLine()) {
        String line = scan.nextLine();
        // 按逗号分割字段,适配CSV格式
        String[] fields = line.split(",");
        
        // 从分割后的数组中提取各字段
        String id = fields[0];
        String brand = fields[1];
        String model = fields[2];
        String type = fields[3];
        int yearOfManufacture = Integer.parseInt(fields[4]);
        int numSeats = Integer.parseInt(fields[5]);
        String color = fields[6];
        double rentalPerDay = Double.parseDouble(fields[7]);
        double insurancePerDay = Double.parseDouble(fields[8]);
        double serviceFee = Double.parseDouble(fields[9]);
        // 只读取一次discount字段,避免重复操作
        double discount = fields[10].equals("N/A") ? 0 : Double.parseDouble(fields[10]);

        // 打印验证数据
        System.out.println(id);
        System.out.println(brand);
        System.out.println(model);
        System.out.println(type);
        System.out.println(yearOfManufacture);
        System.out.println(numSeats);
        System.out.println(color);
        System.out.println(rentalPerDay);
        System.out.println(insurancePerDay);
        System.out.println(serviceFee);
        System.out.println(discount);

        // 创建车辆对象并加入集合
        Car newCar = new Car(id, brand, yearOfManufacture, numSeats, rentalPerDay, insurancePerDay, serviceFee,
                discount, model, type, color);
        vehicleArray.add(newCar);
    }
    // 关闭Scanner释放资源
    scan.close();
}

关键修改说明

  • 逐行读取+字段分割:用hasNextLine()判断是否还有记录,nextLine()获取整行后用split(",")拆分字段,彻底避免Scanner分隔符的混乱问题。
  • 避免重复读取:处理discount时只读取一次字段值,解决原代码中重复调用scan.next()导致的字段跳过和错位问题。
  • 资源释放:添加scan.close()关闭Scanner,避免资源泄漏。

内容的提问来源于stack exchange,提问作者happy days

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:50:28