Как вы отличаете -1 от 0xff при чтении байта из Java FileInputStream? - PullRequest
2 голосов
/ 15 сентября 2011

Итак, мне нужно было пройти тест на собеседование, где я должен был написать мини-приложение, которое выполняло бы простое шифрование XOR, и натолкнулся на этот вопрос. Я использовал FileInputReader для извлечения каждого байта, выполнения операции XOR с ключом и вывода результата обратно в FileOutputStream. Вот что заставило меня задуматься.

FileInputStream возвращает тип int 32-битного со знаком. Получая только один байт, вы можете привести его к типу «байт». FileInputStream также возвращает -1, если достигает EOF. Но -1 == 0xff в двоичном двоичном коде дополнения, так что, если чтение байта действительно 0xff, а не EOF?

Является ли 0xff байтом, который математически никогда не будет возвращен, за исключением особых случаев (таких как EOF)? Или это ситуация, которую вам, возможно, придется учитывать в зависимости от данных, которые вы читаете?

Ответы [ 4 ]

13 голосов
/ 15 сентября 2011

Нет, -1 в int - это не 0xff, а 0xffffffff. int - это 32 бита в Java.

Перед приведением значения к byte убедитесь, что оно равно -1.

Документация API метода read класса FileInputStream объясняет это:

Считывает следующий байт данных из этого входного потока. Байт значения возвращается в виде целого числа в диапазоне от 0 до 255. Если байт не доступен, поскольку достигнут конец потока, возвращается значение -1. Этот метод блокируется до тех пор, пока не будут доступны входные данные, не обнаружен конец потока или не сгенерировано исключение.

Таким образом, если на входе найден байт со значением 0xff, метод read вернет int со значением 255 (0xff). Только в EOF он вернет -1 (что составляет 0xffffffff при сохранении в int).

2 голосов
/ 15 сентября 2011

Вы могли бы:

int value = is.read();
if (value == -1)
   // the end!
else
{
   byte b = (byte) value;
   // use b
}

В любом случае, я должен использовать чтение чанков (попытаться прочитать в байтовый массив), и если число возвращаемых байтов равно нулю, то мы закончили:

int count;
byte[] buffer = new byte[8192];
while ((count = is.read(buffer)) > 0) {
   // use buffer from pos 0 to pos count-1
}
1 голос
/ 15 сентября 2011

0xff только -1 в базе 256, вы работаете в базе 2 ^ 32, так что нет путаницы. Даже если вы написали (signed char)-1 (да, я знаю, что это недопустимая Java, потерпите меня), она все равно будет записана как 0xff.

Вы можете смело предположить, что любой отрицательный возврат является ошибкой, а обычные байтовые значения - это то, что записано в файле дословно.

0 голосов
/ 15 сентября 2011

Метод чтения не реализован в классе FileInputStream, он должен иметь специальную реализацию для ОС, которая расскажет, как на самом деле проверяется обработка EOF.

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