Java 为什么我总是用这段代码获取ArrayIndexOutOfBoundsException?
我是一个Java新手,似乎不明白为什么这个粗糙的20分钟应用程序会抛出这个异常 基本上,我正在解析一个192MB(是的,192MB)制表符分隔的文本文件,并将内容存储到MongoDB中Java 为什么我总是用这段代码获取ArrayIndexOutOfBoundsException?,java,exception,Java,Exception,我是一个Java新手,似乎不明白为什么这个粗糙的20分钟应用程序会抛出这个异常 基本上,我正在解析一个192MB(是的,192MB)制表符分隔的文本文件,并将内容存储到MongoDB中 package get_alternatenames; import java.io.BufferedReader; import java.io.FileReader; import com.mongodb.Mongo; import com.mongodb.DB; import com.mongodb.D
package get_alternatenames;
import java.io.BufferedReader;
import java.io.FileReader;
import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import java.util.Set;
/**
*
* @author cbmeeks
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
String alternateNamesFileName = "/Users/cbmeeks/Projects/GetData/geonames/alternateNames.txt";
String line;
// MongoDB
Mongo m = new Mongo("localhost", 27017);
DB db = m.getDB("mydb");
// Build AlternateNames
DBCollection altNames = db.getCollection("alternatenames");
BufferedReader bReader = new BufferedReader(new FileReader(alternateNamesFileName));
int isPreferredName = 0;
int isShortName = 0;
int lines = 0;
System.out.println("Starting AlternateNames import...");
while ((line = bReader.readLine()) != null) {
String l[] = line.split("\t");
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", l[0]);
altName.put("geonameId", l[1]);
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
isPreferredName = 0;
isShortName = 0;
try {
if (l[4] != null) {
isPreferredName = Integer.parseInt(l[4]);
}
} catch (ArrayIndexOutOfBoundsException ex) {
isPreferredName = 0;
} catch (Exception ex) {
isPreferredName = 0;
}
try {
if (l[5] != null) {
isShortName = Integer.parseInt(l[5]);
}
} catch (ArrayIndexOutOfBoundsException ex) {
isShortName = 0;
} catch (Exception ex) {
isShortName = 0;
}
altName.put("isPreferredName", isPreferredName);
altName.put("isShortName", isShortName);
altNames.insert(altName);
lines++;
}
bReader.close();
System.out.println("Number of lines parsed: " + lines);
System.out.println("Creating indexes...");
altNames.createIndex(new BasicDBObject("geonameId", 1));
altNames.createIndex(new BasicDBObject("isoLanguage", 1));
altNames.createIndex(new BasicDBObject("alternateName", 1));
}
}
我知道这不是世界上最漂亮的代码。实际上,它似乎一直工作到最后。它成功导入540万条记录,然后以以下内容结束:
Starting AlternateNames import...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
Java Result: 1
BUILD SUCCESSFUL (total time: 2 minutes 58 seconds)
我似乎找不到问题所在。我试图搜索文本文件以找到问题,但在192MB的内存下,除了MacVIM之外,似乎没有任何东西能够处理它,我无法完全理解该程序。哈哈
但我确信它没有完成文件。当我转到文本文件中导入的最后一条记录(基于MongoDB中的记录计数)时,它看起来很好……但我可能遗漏了什么
有什么建议吗
谢谢
顺便说一句,Java在不到3分钟的时间内解析了这个文本文件,真是太好了…为什么不添加这样一个数组长度检查呢
String l[] = line.split("\t");
if(l.length == 6 )
{
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", l[0]);
altName.put("geonameId", l[1]);
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
...
为什么不添加这样的数组长度检查
String l[] = line.split("\t");
if(l.length == 6 )
{
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", l[0]);
altName.put("geonameId", l[1]);
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
...
既然你还没有指出你的异常在哪一行,我就用我的心理调试技巧 我的灵力告诉我,你的文件末尾有一个空行,当你去寻找其中的字段时,你会得到一个例外,因为空行上没有字段
要么寻找一个空行,要么不要试图寻找不存在的字段。既然你还没有指出你的异常在哪一行,我将使用我的心理调试技能 我的灵力告诉我,你的文件末尾有一个空行,当你去寻找其中的字段时,你会得到一个例外,因为空行上没有字段 请查找空行,或者不要尝试查找不存在的字段。本节
while ((line = bReader.readLine()) != null) {
String l[] = line.split("\t");
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", l[0]);
altName.put("geonameId", l[1]);
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
是唯一一个按索引访问数组元素但不在ArrayIndexOutOfBounds的try/catch块中的部分,因此必须在此处的某个位置抛出异常。因此,只要你碰到少于4个元素的线,它就会爆炸。在输入代码的这一部分之前,用try-catch或按照Bala的建议进行包装,并测试l的长度
我希望在几乎所有从外部源提取数据的地方进行某种检查,并且需要正确的内容才能正常工作 本节
while ((line = bReader.readLine()) != null) {
String l[] = line.split("\t");
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", l[0]);
altName.put("geonameId", l[1]);
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
是唯一一个按索引访问数组元素但不在ArrayIndexOutOfBounds的try/catch块中的部分,因此必须在此处的某个位置抛出异常。因此,只要你碰到少于4个元素的线,它就会爆炸。在输入代码的这一部分之前,用try-catch或按照Bala的建议进行包装,并测试l的长度
我希望在几乎所有从外部源提取数据的地方进行某种检查,并且需要正确的内容才能正常工作 这是我的正确代码。谢谢大家的提示
package get_alternatenames;
import java.io.BufferedReader;
import java.io.FileReader;
import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import java.util.Set;
/**
*
* @author cbmeeks
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
String alternateNamesFileName = "/Users/cbmeeks/Projects/GetData/geonames/alternateNames.txt";
String line;
// MongoDB
Mongo m = new Mongo("localhost", 27017);
DB db = m.getDB("MyDB");
// Build AlternateNames
DBCollection altNames = db.getCollection("alternatenames");
BufferedReader bReader = new BufferedReader(new FileReader(alternateNamesFileName));
int isPreferredName = 0;
int isShortName = 0;
int lines = 0;
System.out.println("Starting AlternateNames import...");
while ((line = bReader.readLine()) != null) {
try {
String l[] = line.split("\t");
if (l.length >= 4) {
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", Integer.parseInt(l[0]));
altName.put("geonameId", Integer.parseInt(l[1]));
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
isPreferredName = 0;
isShortName = 0;
if (l.length == 5) {
isPreferredName = Integer.parseInt(l[4]);
}
if (l.length == 6) {
isPreferredName = Integer.parseInt(l[4]);
isShortName = Integer.parseInt(l[5]);
}
altName.put("isPreferredName", isPreferredName);
altName.put("isShortName", isShortName);
altNames.insert(altName);
lines++;
}
} catch (Exception ex) {
}
}
bReader.close();
System.out.println("Number of lines parsed: " + lines);
System.out.println("Creating indexes...");
altNames.createIndex(new BasicDBObject("geonameId", 1));
altNames.createIndex(new BasicDBObject("isoLanguage", 1));
altNames.createIndex(new BasicDBObject("alternateName", 1));
}
}
这是我的正确代码,它可以工作。谢谢大家的提示
package get_alternatenames;
import java.io.BufferedReader;
import java.io.FileReader;
import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import java.util.Set;
/**
*
* @author cbmeeks
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
String alternateNamesFileName = "/Users/cbmeeks/Projects/GetData/geonames/alternateNames.txt";
String line;
// MongoDB
Mongo m = new Mongo("localhost", 27017);
DB db = m.getDB("MyDB");
// Build AlternateNames
DBCollection altNames = db.getCollection("alternatenames");
BufferedReader bReader = new BufferedReader(new FileReader(alternateNamesFileName));
int isPreferredName = 0;
int isShortName = 0;
int lines = 0;
System.out.println("Starting AlternateNames import...");
while ((line = bReader.readLine()) != null) {
try {
String l[] = line.split("\t");
if (l.length >= 4) {
BasicDBObject altName = new BasicDBObject();
altName.put("alternateNameId", Integer.parseInt(l[0]));
altName.put("geonameId", Integer.parseInt(l[1]));
altName.put("isoLanguage", l[2]);
altName.put("alternateName", l[3]);
isPreferredName = 0;
isShortName = 0;
if (l.length == 5) {
isPreferredName = Integer.parseInt(l[4]);
}
if (l.length == 6) {
isPreferredName = Integer.parseInt(l[4]);
isShortName = Integer.parseInt(l[5]);
}
altName.put("isPreferredName", isPreferredName);
altName.put("isShortName", isShortName);
altNames.insert(altName);
lines++;
}
} catch (Exception ex) {
}
}
bReader.close();
System.out.println("Number of lines parsed: " + lines);
System.out.println("Creating indexes...");
altNames.createIndex(new BasicDBObject("geonameId", 1));
altNames.createIndex(new BasicDBObject("isoLanguage", 1));
altNames.createIndex(new BasicDBObject("alternateName", 1));
}
}
你应该知道哪一行引发了异常,你可以通过查看行号然后检查代码来理解。你应该知道哪一行引发了异常,你可以通过查看行号然后检查代码来理解。哈哈~我也能感觉到你的精神力量。嗯,我是Java新手,没有看到线路在哪里被提到,而且很累。但是谢谢你机智的回答。哈哈~我也能感觉到你的灵力。嗯,我是爪哇的新手,不知道这句台词是在哪里提到的,而且很累。谢谢你机智的回答。我没想到。这很有效。然而,我现在从540万行增加到9500行。哈哈。如果我去掉最后两个字段,它似乎也能起作用。所以我想我需要考虑可变长度字段。我将在每行中加入一些条件长度检查。谢谢杜尔。我没想到。这很有效。然而,我现在从540万行增加到9500行。哈哈。如果我去掉最后两个字段,它似乎也能起作用。所以我想我需要考虑可变长度字段。我将在每行中加入一些条件长度检查。谢谢谢谢你的信息。我想我比我想象的要累。哈哈,这不是真正的生产代码,只是一个小项目。我在下面发布了我的固定示例(带有try/catch),感谢您提供的信息。我想我比我想象的要累。哈哈,这不是真正的生产代码,只是一个小项目。我在下面发布了我的固定示例(带有try/catch)