简体   繁体   中英

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. 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.

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.

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.

Sample records from source file:

8030180001~tdurgin1~INA~Y

8030180001~katrn50~IO15~Y

8030180002~richburg~IO15~D

log when it fails:

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.861 8433823735 bobbyteetor BN222 Y

2018-03-05 04:48:10.882 after insert

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

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

2018-03-05 04:48:10.906 after new read1 scanner

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.

Consider using if(read1.hasNext()) to make sure you have a next token first.

One side note is that creating a scanner for every line is a bit overkill. Consider just doing 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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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