简体   繁体   English

Java Scanner类提供java.util.NoSuchElementException

[英]Java Scanner class gives java.util.NoSuchElementException

I have tried to look thru existing questions but don't see anything that matches my problem. 我试图通过现有问题来查找,但没有发现与我的问题相符的内容。

I am trying to read a text file from a ftp server which has 30000 lines. 我正在尝试从具有30000行的ftp服务器读取文本文件。 Each line is a record with ~ separated values. 每行都是一个带有〜分隔值的记录。

Once i get a record and those values I insert them in a table. 一旦获得记录和这些值,便将它们插入表中。

I am using a scanner class to scan the file and then for each record I am using another scanner class with ~ delimiter to read those records. 我正在使用一个扫描程序类来扫描文件,然后对于每个记录,我正在使用另一个带有〜分隔符的扫描程序类来读取这些记录。

The program runs everyday and most of the time completes without any problem. 该程序每天运行,并且大部分时间都可以正常运行。

But once in a while it fails with NoSuchElementException. 但是有时会由于NoSuchElementException而失败。

I have logs which show that at some point.. say after 24000 records the nextline scanner gets is not complete.. it get partial line and then delimited scanner fails to read the next value and gives this error. 我的日志显示在某个时候..说24000条记录后,nextline扫描仪获取未完成..它获取了部分行,然后定界的扫描仪无法读取下一个值并给出此错误。

If I run that program again on same source file. 如果我在相同的源文件上再次运行该程序。 It will run with no issue. 它将毫无问题地运行。 I am not sure if this related to environment or data size or the code.. any input or direction to check will be really appreciated. 我不确定这是否与环境或数据大小或代码有关。是否需要检查任何输入或方向? Or any better suggestions.. 或任何更好的建议。

Code snippet from the method I wrote: 我编写的方法的代码段:

Scanner read = new Scanner(is); 扫描仪读取=新的扫描仪; // is is the inputstream //是输入流

        String telNo, usrID, srvTyp, status, line;
        read.nextLine(); // i am purposely skipping the first line

        while (read.hasNextLine()) {
            m_LogMgr.logMessage(LogManager.LOG_EVENT,
                    "before read.nextLine", 10, 2);
            line = read.nextLine();
            m_LogMgr.logMessage(LogManager.LOG_EVENT, line, 10, 2);
            if (line == null || line.trim().length() < 1) {
                m_LogMgr.logMessage(LogManager.LOG_EVENT,
                        "continue as i got a blank line", 10, 2);
                continue;
            }

            Scanner read1 = new Scanner(line);
            m_LogMgr.logMessage(LogManager.LOG_EVENT,
                    "after new read1 scanner", 10, 2);
            read1.useDelimiter("~");
            telNo = read1.next();
            usrID = read1.next();
            srvTyp = read1.next();
            status = read1.next();

            m_LogMgr.logMessage(LogManager.LOG_EVENT, telNo + " " + usrID
                    + " " + srvTyp + " " + status, 10, 2);
            callInsert(telNo, usrID, srvTyp, status);
            m_LogMgr.logMessage(LogManager.LOG_EVENT, "after insert", 10, 2);
            read1.close();

        }
        read.close();

.. .. and finally i close the input stream and disconnect ftpclient. .. ..最后,我关闭输入流并断开ftpclient的连接。

Sample records from source file: 来自源文件的样本记录:

8030180001~tdurgin1~INA~Y 8030180001〜tdurgin1〜INA〜ÿ

8030180001~katrn50~IO15~Y 8030180001〜katrn50〜IO15〜ÿ

8030180002~richburg~IO15~D 8030180002〜里奇堡〜IO15〜d

log when it fails: 失败时记录:

2018-03-05 04:48:10.846 8433823735~bobbyteetor~BN222~Y 2018-03-05 04:48:10.846 8433823735〜bobbyteetor〜BN222〜Y

2018-03-05 04:48:10.855 after new read1 scanner 2018-03-05 04:48:10.855新的read1扫描仪之后

2018-03-05 04:48:10.861 8433823735 bobbyteetor BN222 Y 2018-03-05 04:48:10.861 8433823735 bobbyteetor BN222 Y

2018-03-05 04:48:10.882 after insert 插入后2018-03-05 04:48:10.882

2018-03-05 04:48:10.895 before read.nextLine read.nextLine之前的2018-03-05 04:48:10.895

2018-03-05 04:48:10.905 8433823736~gra 2018-03-05 04:48:10.905 8433823736〜gra

2018-03-05 04:48:10.906 after new read1 scanner 2018年3月5日04:48:10.906新的read1扫描仪之后

2018-03-05 04:48:10.991 e.toString =java.util.NoSuchElementException 2018-03-05 04:48:10.991 e.toString = java.util.NoSuchElementException

Clearly, the problem is your line, 8433823736~gra , lacks enough tokens to make all the necessary next() calls. 显然,问题是您的行8433823736~gra缺少足够的令牌来进行所有必要的next()调用。

Consider using if(read1.hasNext()) to make sure you have a next token first. 考虑使用if(read1.hasNext())来确保首先拥有下一个标记。

One side note is that creating a scanner for every line is a bit overkill. 附带说明的是,为每条线创建一个扫描仪有点过分。 Consider just doing String[] tokens = read1.next().split("~"); 考虑只做String[] tokens = read1.next().split("~"); and using tokens[0] etc. Then you know right away that since you're supposed to have 4 tokens, if(tokens.length != 4) System.out.println("Skipping line " + line + " because it is malformed"); 并使用tokens[0]等。然后您马上就知道,因为您应该有4个令牌,所以if(tokens.length != 4) System.out.println("Skipping line " + line + " because it is malformed");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM