Java FileInputStream.read() пропускает байты

Я читаю двоичный файл по одному байту за раз, используя Java FileInputStream.read() и отслеживая позицию в файле, увеличивая переменную i. Я ищу конкретный символ, и для первой части бинарного файла возвращается правильное смещение.

Однако позже в файле смещения (найденные i) начинают уменьшаться по сравнению с фактическими смещениями в файле. (Например, символ в 0x4c5 был неправильно прочитан как 0x4c3.) Таким образом, FileInputStream.read() пропускает байты. Постепенно i стало значительно меньше, чем фактическое смещение файла (к концу оно стало на 60 байт меньше).

Вот часть моего кода.

in = new FileReader(path);
int c = 0;
int i = -1;

while (c != -1) {
    i++;
    try {
        c = in.read();
        if (c == 0x47) {
            print("Found G at 0x" + Integer.toHexString(i));
        }
    } catch(IOException e) ...

Что может быть причиной этого? Более того, как этого избежать?

Используйте FileInputStream для двоичного файла.

Saurav Kumar 13.12.2020 07:49

«Я читаю двоичный файл по одному байту за раз, используя Java FileInputStream.read() ...» - это НЕ то, что делает код, который вы нам показали. И это, вероятно, причина вашей проблемы (IMO). Если нет, вам нужно показать нам минимально воспроизводимый пример, демонстрирующий вашу реальную проблему.

Stephen C 13.12.2020 07:57

За исключением того, что вы читаете текстовый файл (читатели имеют текстовую базу), поэтому c может быть двухбайтовым.

NomadMaker 13.12.2020 08:24
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
143
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что проблема в том, что вы на самом деле читаете с Reader, а не с InputStream. Конечно, это то, что вы делаете в коде, который вы нам показали!

Вызов Reader.read() потребляет один или несколько байтов1 и возвращает один char, представленный этими байтами.

Решение: не используйте Reader для чтения двоичного файла. Используйте InputStream или какой-либо подкласс InputStream.


1 - The actual behavior depends on the character encoding that FileReader uses. For example, if the encoding is UTF-8, then bytes that are greater than 0x7f are treated as part of a multi-type character. If you read arbitrary binary data as if it was UTF-8 encoded text, the result is liable to be garbage. Certainly, I would expect the offsets to be "off".

Другие вопросы по теме