java jvm在使用Scanner时抛出NoTouchElementException
我正面临一个我真的不明白的问题。 我设计的程序是从文件中读取信息,然后生成相关报告
第一次,我打开了我需要的所有文件:
clientesarq = new File(args[1]);
fornecedoresarq = new File(args[3]);
produtosarq = new File(args[5]);
然后我使用java。util。要循环通过它们的扫描仪:
leitor = new Scanner(clientesarq);
leitor.nextLine();
/* leitura e armazenamento dos clientes em mapa */
while(leitor.hasNextLine()) {
Cliente c = pd.novoCliente(leitor);
clientes.addCliente(c);
}
leitor = new Scanner(fornecedoresarq);
leitor.nextLine();
/* leitura e arazenaento dos fornecedores em mapa */
while(leitor.hasNextLine()) {
Fornecedor f = pd.novoFornecedor(leitor);
fornecedores.addFornecedor(f);
}
当我的程序到达代码的这一部分时,JVM向我抛出NoTouchElementException
leitor = new Scanner(produtosarq);
leitor.nextLine(); /* EXCEPTION HERE */
/* leitura e armazenamento dos produtos em mapa */
while(leitor.hasNextLine()) {
Produto p = pd.novoProduto(leitor);
produtos.addProduto(p);
}
我真的很想知道为什么我会得到这个例外,正如你所看到的,代码和其他的完全一样。有吗
您可以在此处获取所有需要的文件:https://www.dropbox.com/sh/c48roudfwuj7qzu/AAAMn_OFGXJFHEjVJyZ7piCPa
# 1 楼答案
只是一个猜测,但可能你试图读取的文件没有任何信息。在得到下一行之前,一定要检查它是否有下一行
# 2 楼答案
使用^{} 字符集从能够以Unicode格式表示每个字符的文件中读取
在这里,它将使用指定的字符集(这里是UTF-8)将文件中的字节转换为字符,并使其可读
Scanner
# 3 楼答案
指定字符集并不能解决我的问题。这篇帖子像是评论,因为我还没有完全发现这个问题,但我试图用我迄今为止的发现来解释问题的原因
我发现another post与辅助资源具有相同的问题。在这两种情况下,文件的第一行都以ASCII字符13
carriage return
结尾,我认为扫描仪应该将其作为行分隔符。作为一个理智的检查,我执行了一个BufferedReader readLine(),效果很好。深入挖掘,我克隆了扫描仪的来源,并在readInput行849:n = source.read(buf);
上结束在确定
source
的类型是sun.nio.cs.StreamDecoder
之后,我克隆了这个类并研究了readImpl。在这两种情况下,第324行int n = readBytes();
将整个文件读入缓冲区,击中continue
并返回到第316行CoderResult cr = decoder.decode(bb, cb, eof);
。此时cr
正在包装一个被扫描器catch (IOException ioe)
消耗的MalformedInputException由于我能够在克隆的源代码中重现这个问题,我打印了stacktrace:
运行时的解码器是sun.nio.cs.UTF_8。我现在已经停止挖掘,因为它已经进入上午时间,我可能会编辑进一步的发现
现在的主要问题是,为什么输入的最后一个字符会杀死解码器