Почему я продолжаю получать ArrayIndexOutOfBoundsException с этим кодом? - PullRequest
0 голосов
/ 02 апреля 2011

Я новичок в Java и не могу понять, почему это грубое 20-минутное приложение выдает это исключение.

По сути, я анализирую 192 МБ (да, 192 МБ) текста с разделителями табуляциифайл и хранение содержимого в MongoDB.

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));

    }
}

Я знаю, что это не самый красивый код в мире.И это на самом деле, кажется, работает до конца.Он успешно импортирует 5,4 миллиона записей, а затем заканчивается:

Starting AlternateNames import...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
Java Result: 1
BUILD SUCCESSFUL (total time: 2 minutes 58 seconds)

Я не могу найти, в чем проблема.Я пытался найти текстовый файл, чтобы найти проблему, но на 192 МБ, кажется, ничто не может справиться с этим, кроме MacVIM, и я не могу полностью разобраться с этой программой.lol

Но я уверен, что файл не заканчивается.Когда я перехожу к последней записи, импортированной в текстовый файл (на основе количества записей в MongoDB), она выглядит нормально ... но я мог что-то упустить.

Есть предложения?

Спасибо.

Кстати, спасибо Java за анализ этого текстового файла менее чем за 3 минуты ...

Ответы [ 4 ]

2 голосов
/ 02 апреля 2011

Почему бы вам не добавить проверку длины массива следующим образом

     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]);
             ... 
1 голос
/ 02 апреля 2011

Этот раздел

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]);

является единственным разделом, в котором вы обращаетесь к элементам массива по индексу, но не находитесь в блоке try / catch для ArrayIndexOutOfBounds, поэтому исключение должно быть выдано где-то здесь,Поэтому он будет бум везде, где вы попадете на линию с менее чем 4 элементами.Оберните все это в попытку поймать или сделать, как предлагает Бала, и проверить длину l, прежде чем вводить эту часть кода.

Я бы хотел провести какие-то проверки практически везде, где бы вы ни находились ».вы будете получать данные из внешнего источника, и вам потребуется правильный контент для правильной работы.

0 голосов
/ 02 апреля 2011

Вот мой исправленный код, который работает.Спасибо всем за советы.

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));

    }
}
0 голосов
/ 02 апреля 2011

Поскольку вы не указали, на какой строке находится ваше исключение, я собираюсь использовать мои навыки психической отладки.

Мои психические силы говорят мне, что у вас есть пустая строка в конце вашего файла, и когда вы идете искать поля в нем, вы получаете исключение, потому что в пустой строке нет полей.

Либо ищите пустую строку, либо не пытайтесь искать поля, которых там нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...