Использование BufferedReader для подсчета строк в многомерном массиве

Я использую BufferedReader для чтения файла .csv. У меня нет проблем с чтением файла и извлечением данных. Однако проблема, которая у меня есть, заключается в том, что мне нужно жестко закодировать объявление моего массива. Например:

        String[][] numbers=new String[5258][16];

В файле .csv, который я использовал, было 5258 строк и 16 столбцов. Я хотел бы иметь возможность сделать что-то вроде этого:

        String[][] numbers=new String[rowsInFile][16];

Другими словами, я хочу, чтобы переменная rowsInFile была эквивалентна количеству строк в файле (я не хочу считать столбцы, потому что каждый файл .csv, который я буду запускать в этой программе, имеет 16 столбцов).

Вот код, который у меня есть до сих пор:

        int row = 0;
        int col = 0;

        String fileInput = JOptionPane.showInputDialog(null, 
                "Please enter the path of the CSV file to read:");

        File file = new File(fileInput);

        BufferedReader bufRdr;
        bufRdr = new BufferedReader(new FileReader(file));
        String line = null;

        //get rows in the file
        int rowsInFile = 0;
        while(bufRdr.readLine() != null) {
            rowsInFile++;
            row++;
        }
        String[][] numbers=new String[rowsInFile][16];

        //read each line of text file
        row = 0;
        while((line = bufRdr.readLine()) != null) {
            StringTokenizer st = new StringTokenizer(line,",");
            col=0;

            while (st.hasMoreTokens()) {
                //get next token and store it in the array
                numbers[row][col] = st.nextToken();
                col++;
            }
            row++;
        }

Однако я получаю исключение нулевого указателя. Есть идеи, что мне делать?

P.S. Да, этот код окружен оператором try/catch.


person Mxyk    schedule 08.08.2011    source источник
comment
Какая строка выдает NPE, ничто в опубликованном вами коде не выглядит подозрительным.   -  person Qwerky    schedule 08.08.2011
comment
Извините, что звучу так новичком, но я на самом деле даже не знаю, как проверить. Если я нажму на отображаемую ошибку, она просто откроет новое окно под названием «Создать точку останова для java.lang.NullPointerException».   -  person Mxyk    schedule 08.08.2011


Ответы (3)


Проблема в том, что, пройдя BufferedReader один раз, вы не сможете вернуться к нему снова. Другими словами, вы должны использовать новый BufferedReader.

bufRdr = new BufferedReader(new FileReader(file));
row = 0;
while((line = bufRdr.readLine()) != null) {

В качестве альтернативы вы можете использовать структуру динамического массива, например ArrayList<String[]> или LinkedList<String[]>, для хранения строк.

LinkedList<String[]> numbers = new LinkedList<String[]>();

while( (line = bufRdr.readLine()) != null ) {
    numbers.add(line.split(","));
}

Затем вместо numbers[i][j] вы используете numbers.get(i)[j].

person tskuzzy    schedule 08.08.2011
comment
Я попытался добавить bufRdr = new BufferedReader(new FileReader(file)); после String[][] number=new String[rowsInFile][16]; снова, чтобы создать новый BufferedReader, но я все еще получаю исключение нулевого указателя. - person Mxyk; 08.08.2011
comment
Кроме того, я немного не знаком с использованием списков. Не могли бы вы объяснить, как я могу использовать их для хранения строк? - person Mxyk; 08.08.2011
comment
@Mike Gates: Хм, это странно. Во всяком случае, я отредактировал свой ответ, включив в него пример с использованием LinkedList. - person tskuzzy; 08.08.2011
comment
Я принял ваш ответ, однако до сих пор не могу преобразовать список в строку[][]. - person Mxyk; 08.08.2011

Вместо массива используйте что-то динамическое, например список. Например:

List<String[]> data = new ArrayList<String[]>();

Также использование метода split() String упростит загрузку строки.

person jzd    schedule 08.08.2011
comment
Я на самом деле не знаком с использованием списка. Я видел его раньше, но я никогда не использовал его. Не могли бы вы уточнить немного больше, пожалуйста? - person Mxyk; 08.08.2011
comment
@mike-gates См. руководство: download.oracle.com/javase/tutorial/ коллекции/index.html - person Walter Laan; 08.08.2011

Ваша проблема в том, что BufferedReaders работают, читая до конца файла, а затем застревают там. Ваш код требует дважды прочитать файл, но поскольку вы уже достигли EOF, BufferedReader застревает, возвращая значение null. Я склонен решать эту проблему, помещая строки в ArrayList и используя метод size() для получения количества строк. Исходный код выглядит примерно так:

    int rowsInFile=0;
    ArrayList<String> lines = new ArrayList<String>();
    String tmp = "";
    while(tmp=bugRdr.readLine())
    {
        lines.add(tmp);
    }

    rowsInFile = lines.size();
    String[][] numbers = new String[rowsInFile][16];

    int row = 0;
    for(String line : lines)
    {
        StringTokenizer st = new StringTokenizer(line,",");
        col=0;

        while (st.hasMoreTokens()) {
        //get next token and store it in the array
            numbers[row][col] = st.nextToken();
            col++;
        }
        row++;
    }
person smitty1110    schedule 08.08.2011