提问人:Sumitr Banik 提问时间:3/20/2022 最后编辑:Alexander IvanchenkoSumitr Banik 更新时间:3/21/2022 访问量:306
使用 Scanner.useDelimiter() 和 hasNextLine() 从文件中读取 - NoSuchElementException
Reading from the file with Scanner.useDelimiter() and hasNextLine() - NoSuchElementException
问:
当我尝试从文本文件加载数据时,使用这样的数据
java;sdf;2.0;3.0;
cpp;sdks;24.6;89.0;
我正在用这个代码得到。NoSuchElementException
public void loadFile() {
Scanner scan = null;
int n = 0;
try {
scan = new Scanner(new File(this.filename)).useDelimiter(";");
this.items.clear();
while (scan.hasNextLine()) {
String name = scan.next();
String barcode = scan.next();
double unitPrice = scan.nextDouble();
double shipCost = scan.nextDouble();
Product newProduct = new Product(name, barcode, unitPrice, shipCost);
this.items.add(newProduct);
n++;
}
}
catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} catch (InputMismatchException e) {
System.err.println("Caught InputMismatchException: " + e.getMessage());
System.out.println(n + " products loaded!");
} catch (NoSuchElementException e) {
System.err.println("Attempt to read past end of file");
} catch (IllegalStateException e) {
System.err.println("Attempt to read a closed file");
} finally {
if (scan != null)
scan.close();
}
}
答:
0赞
Arka Bandyopadhyay
3/20/2022
#1
hasNextLine() 方法等待 unitl 没有 nextLine but hasNext() 等到有下一个令牌
对于解决方案透视图,请使用:
while (scan.hasNext()) {
String name = scan.next();
String barcode = scan.next();
double unitPrice = scan.nextDouble();
double shipCost = scan.nextDouble();
System.out.println(name);
n++;
}
这将解决您的问题
评论
0赞
Sumitr Banik
3/21/2022
即使使用 hasNext() 方法,我也会得到 NoSuchElementException
0赞
Arka Bandyopadhyay
4/6/2022
在我的本地机器上运行良好
0赞
Alexander Ivanchenko
3/21/2022
#2
有几种方法可以解决这个问题。
1. 当当前行上的所有令牌都已读取完毕后,前进到下一行。
为此,请在循环末尾添加该行。Method 将返回整行当前行(该值将被省略),并将扫描仪位置设置在下一行的开头。scan.nextLine()
nextLine()
while (scan.hasNextLine()) {
// reading tokens and creating new Product
scan.nextLine();
}
2. 将循环中的条件更改为 。这样它就会检查是否存在更多令牌。while
scan.hasNext()
但是会出现另一个问题:从第二项开始声明所有项目名称将在开头包含一个新行字符 ()。\n
要处理它,您可以应用名称,将分隔符更改为 \n\r' 字符以及省略分号。strip()
"[;\\r\\n]+" (with that every new line character
and carriage return
can = new Scanner(new File(this.filename)).useDelimiter("[;\\r\\n]+");
this.items.clear();
while (scan.hasNext()) {
// code inside the loop remains the same
}
这种方法的缺点是:检查单个标记是否存在,不能清楚地显示读取由四个标记组成的行的意图。scan.hasNext()
3.最后一个选项是逐行读取文件,然后对其应用,这将给出一个字符串数组。scan.nextLine()
split(";")
此解决方案可能看起来有点乏味,因为它需要手动处理拆分以分析值。double
while (scan.hasNextLine()) {
String[] line = scan.nextLine().split(";");
String name = line[0];
String barcode = line[1];
double unitPrice = Double.parseDouble(line[2]);
double shipCost = Double.parseDouble(line[3]);
Product newProduct = new Product(name, barcode, unitPrice, shipCost);
this.items.add(newProduct);
}
上述所有解决方案都使用提供的文件示例和虚拟类进行测试。Product
输出(列表内容)items
[Product{name='java', barcode='sdf', unitPrice=2.0, shipCost=3.0}, Product{name='cpp', barcode='sdks', unitPrice=24.6, shipCost=89.0}]
评论
0赞
Sumitr Banik
3/21/2022
第三个选项奏效了,非常感谢!
评论