我试图通过现有的问题来看,但没有看到任何与我的问题相符的东西。
我试图从具有30000行的ftp服务器读取文本文件。每行都是带有〜分隔值的记录。
一旦我得到一个记录和那些值,我将它们插入表中。
我正在使用扫描仪类来扫描文件,然后对于每个记录,我使用另一个带有〜分隔符的扫描程序类来读取这些记录。
该程序每天运行,大部分时间都没有任何问题。
但偶尔它会因NoSuchElementException而失败。
我有日志显示,在某些时候..说24000记录之后,下一行扫描仪得到的不完整..它得到部分行,然后分隔扫描器无法读取下一个值并给出此错误。
如果我在同一源文件上再次运行该程序。它将运行没有问题。我不确定这是否与环境或数据大小或代码有关..任何输入或检查方向都将非常感激。或者任何更好的建议..
我写的方法的代码片段:
扫描仪读取=新扫描仪(是); //是输入流
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();
.. ..最后我关闭输入流并断开ftpclient。
源文件中的示例记录:
8030180001~tdurgin1~INA~Y
8030180001~katrn50~IO15~Y
8030180002〜里奇堡〜IO15〜d
失败时记录:
2018-03-05 04:48:10.846 8433823735~bobbyteetor~BN222~Y
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.882插入后
2018-03-05 04:48:10.895 read.nextLine之前
2018-03-05 04:48:10.905 8433823736~游戏
2018-03-05 04:48:10.906新的read1扫描仪之后
2018-03-05 04:48:10.991 e.toString = java.util.NoSuchElementException
显然,问题是你的线路,8433823736~gra
,缺乏足够的令牌来进行所有必要的next()
呼叫。
考虑使用if(read1.hasNext())
确保首先拥有下一个令牌。
一方面注意,为每一行创建一个扫描仪有点矫枉过正。考虑只是做String[] tokens = read1.next().split("~");
和使用tokens[0]
等。然后你马上知道,因为你应该有4个令牌,if(tokens.length != 4) System.out.println("Skipping line " + line + " because it is malformed");