使用 Scanner.useDelimiter() 和 hasNextLine() 从文件中读取 - NoSuchElementException
当我尝试从 textfile 加载数据时,使用这样的数据,
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();
}
}
When I try to load the data from the textfile, with data like this
java;sdf;2.0;3.0;
cpp;sdks;24.6;89.0;
I'm getting the NoSuchElementException
with this code.
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
hasNextLine() 方法等待直到没有 nextLine
但 hasNext() 会等到有下一个令牌
对于解决方案的角度使用:
这将解决您的问题
hasNextLine() method waits unitl there is no nextLine
but hasNext() waits until there is next token
For solution perspective use :
This will solve your problem
有几种方法可以解决这个问题。
1.当前行上的所有标记都已读取后,前进到下一行。
为此,请在循环末尾添加行
scan.nextLine()
。方法nextLine()
将返回整个当前行(该值将被省略),并将扫描仪位置设置在下一行的开头。2. 将
while
循环中的条件更改为scan.hasNext()
。这样它就会检查是否存在更多令牌。但是会出现另一个问题:从第二个item开始,所有item名称都将在开头包含一个换行符(
\n
)。要处理它,您可以对名称应用
strip()
,将分隔符更改为"[;\\r\\n]+"(使用每个换行符
\n和回车符
\r` 字符以及分号都将被省略这种方法的缺点:条件
。 scan.hasNext()
检查单个令牌是否存在没有清楚地表明读取由四个标记组成的行的意图3。最后一个选项是使用
scan.nextLine()
逐行读取文件。然后对其应用split(";")
,这将给出一个字符串数组。这个解决方案可能看起来有点乏味,因为它需要处理拆分来解析
double< /code> 值手动
测试上述所有解决方案 。 file-example 和一个虚拟
Product
类Output(
items
列表内容) 。There are several approaches how you can solve this.
1. Advance to the next line when all token on the current line have been read.
For that, add the line
scan.nextLine()
at the end of the loop. MethodnextLine()
will return the whole current line (that value will be omitted) and will set the scanners position at the beginning of the next line.2. Change the condition in the
while
loop toscan.hasNext()
. So that it'll check whether more token exists.But another problem will arise: stating from the second item all item names will contain a new line character (
\n
) at the beginning.To handle it, you can either apply
strip()
on a name, change the delimiter to"[;\\r\\n]+" (with that every new line character
\nand carriage return
\r` character as well as semicolon will be omitted.The drawback of this approach: condition
scan.hasNext()
that check existence of a single token doesn't clearly show the intention to read the line comprised of four tokens.3. The last option is to read the file line by line with
scan.nextLine()
and then applysplit(";")
on it, which will give an array of strings.This solution might look a bit more tedious because it'll require to handle the splitting to parse
double
values manually.All solutions above are tested with the provided file-example and a dummy
Product
class.Output (
items
list contents)