使用Java Scanner读取文本文件时遇无行错误且无法读取最后一项
问题分析与解决方案
问题根源
你的代码每次循环强制读取5行数据(ID、商品名、售价、成本价、空行),但最后一条记录的末尾没有对应的空行。当处理最后一组数据时,读完成本价后尝试读取空行,此时文件已无内容可读取,直接触发NoSuchElementException(即你看到的"No Line Found"错误),导致最后一组数据未完成处理就中断。
同时,while (src.hasNextLine())仅判断当前存在至少一行,但无法保证后续还有足够的行供你连续读取4-5行,逻辑判断不严谨。
解决方案一:先收集非空行再分组处理
这种方式更稳妥,先过滤掉所有空行,再按每4行一组(ID、商品名、售价、成本价)处理数据,完全不受空行位置影响。
import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class FileReaderDemo { public static void main(String[] args) { String filelocation = "file.txt"; ProductList p = new ProductList(); try { File myObj = new File(filelocation); Scanner src = new Scanner(myObj); List<String> validLines = new ArrayList<>(); // 读取所有非空行,自动跳过空分隔行 while (src.hasNextLine()) { String line = src.nextLine().trim(); if (!line.isEmpty()) { validLines.add(line); } } src.close(); // 按每4行一组解析数据 for (int i = 0; i < validLines.size(); i += 4) { // 防止文件格式异常导致数组越界 if (i + 3 >= validLines.size()) break; long id = Long.parseLong(validLines.get(i)); String productName = validLines.get(i+1); double originalPrice = Double.parseDouble(validLines.get(i+2)); double costPrice = Double.parseDouble(validLines.get(i+3)); // 将数据添加到ProductList // p.add(new Product(id, productName, originalPrice, costPrice)); System.out.println(id +"\n"+ productName +"\n"+ originalPrice +"\n"+ costPrice+"\n"); } } catch (FileNotFoundException e) { System.out.println("目标文件未找到"); e.printStackTrace(); } catch (NumberFormatException e) { System.out.println("数据格式错误,无法转换为对应类型"); e.printStackTrace(); } } }
解决方案二:逐行检查读取,兼容无末尾空行场景
如果不想提前收集所有行,可以在每次读取前检查是否还有行可读,避免强制读取不存在的行。
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class FileReaderDemo { public static void main(String[] args) { String filelocation = "file.txt"; ProductList p = new ProductList(); try { File myObj = new File(filelocation); Scanner src = new Scanner(myObj); while (src.hasNextLine()) { // 读取ID long id = Long.parseLong(src.nextLine().trim()); // 读取商品名前先检查是否有行 if (!src.hasNextLine()) break; String productName = src.nextLine().trim(); // 读取售价前检查 if (!src.hasNextLine()) break; double originalPrice = Double.parseDouble(src.nextLine().trim()); // 读取成本价前检查 if (!src.hasNextLine()) break; double costPrice = Double.parseDouble(src.nextLine().trim()); // 空行处理:有就读取,没有就跳过 if (src.hasNextLine()) { String separator = src.nextLine(); if (!separator.trim().isEmpty()) { System.out.println("警告:记录ID " + id + " 后未找到预期的空行"); } } // 处理数据 System.out.println(id +"\n"+ productName +"\n"+ originalPrice +"\n"+ costPrice+"\n"); } src.close(); } catch (FileNotFoundException e) { System.out.println("目标文件未找到"); e.printStackTrace(); } catch (NumberFormatException e) { System.out.println("数据格式错误,无法转换为对应类型"); e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者jwolf
相关产品推荐
相关产品推荐

