NumberFormatException при выборе случайных элементов из большого файла

У меня очень большой файл, который содержит идентификаторы пользователей, подобные этому. Каждая строка в этом большом файле является идентификатором пользователя.

149905320
1165665384
66969324
886633368
1145241312
286585320
1008665352

Итак, в этом большом файле у меня будет около 30 миллионов идентификаторов пользователей. Теперь я пытаюсь выбрать случайный идентификатор пользователя из этого большого файла. Ниже приведена программа, которую я имею, но в какой-то момент она всегда дает мне это исключение, подобное этому, и я не уверен, почему это исключение происходит.

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:59)
    at java.lang.Integer.parseInt(Integer.java:481)
    at java.lang.Integer.parseInt(Integer.java:510)
    at com.host.bulls.service.lnp.RandomReadFromFile.main(RandomReadFromFile.java:65)

Ниже приведена программа -

public static void main(String[] args) throws Exception {

    File f = new File("D:/abc.txt");
    RandomAccessFile file;

    try {

        file = new RandomAccessFile(f, "r");
        long file_size = file.length();

        // Let start
        long chosen_byte = (long)(Math.random() * (file_size - 1));
        long cur_byte = chosen_byte;

        // Goto starting position
        file.seek(cur_byte);

        String s_LR = "";
        char a_char;

        // Get left hand chars
        for (;;)
        {
            a_char = (char)file.readByte();
            if (cur_byte < 0 || a_char == '\n' || a_char == '\r' || a_char == -1) break;
            else 
            {
                s_LR = a_char + s_LR;
                --cur_byte;
                if (cur_byte >= 0) file.seek(cur_byte);
                else break;
            }
        }

        // Get right hand chars
        cur_byte = chosen_byte + 1;
        file.seek(cur_byte);
        for (;;)
        {
            a_char = (char)file.readByte();
            if (cur_byte >= file_size || a_char == '\n' || a_char == '\r' || a_char == -1) break;
            else 
            {
                s_LR += a_char;
                ++cur_byte;
            }
        }

        // Parse ID
        if (cur_byte < file_size) 
        {
            int chosen_id = Integer.parseInt(s_LR);
            System.out.println("Chosen id : " + chosen_id);
        }
        else
        {
            throw new Exception("Ran out of bounds..");
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Есть ли какие-либо проблемы в моем предыдущем коде?

Ответ 1

Я попытался запустить ваш код и нашел еще одну ошибку - вам нужно проверить cur_byte перед следующим образом:

if (cur_byte < file_size) {
    a_char = (char) file.readByte();
}

В противном случае вы получите EOFException.

С вашим образцом abc.txt я не получаю исключение java.lang.NumberFormatException: For input string: "".

Но если я добавлю пустые строки в abc.txt, я получу это исключение раньше или позже. Таким образом, проблема заключается в пустых строках где-то в abc.txt.

Ответ 2

Любая неотвратимая строка, если вы перейдете к методу parseInt, тогда она поднимет NumberFormatException. Как и пустая строка, а также Integer может содержать максимальное и минимальное значение, которое может иметь int, 2147483647 или -2147483648. И если значение выходит за рамки этого, то оно поднимает NumberFormatException

If the string does not contain a parsable integer. ([Documentation][1])

Ответ 3

Кажется, что s_LR содержит пустую строку.

Из того, что я могу предположить, что это может произойти, если у вас есть строки в стиле Windows (\ r\n) и нажмите "\ r" со случайным поиском. Тогда условия break в обеих циклах будут применяться, прежде чем любой char будет добавлен в s_LR.

Sidenote: вы используете очень атипичный стиль кодирования для java. Хотя это не влияет на вашу программу, труднее читать/понимать других программистов на Java, и поэтому вы не можете получить ответ.

Ответ 4

Действительно, похоже, что у вас есть пустая строка в конце файла или в начале файла.

Или одно из чисел, для которых требуется целое число.

Я вижу два решения:

  • Добавить проверку пробелов и пустой строки для каждого элемента, который вы читает из файла.
  • Изменить целочисленное значение на длинное.