Обход без переменных без знака в Java
Я пишу функции сохранения и загрузки файлов для определенного формата файла, который я не могу контролировать, и этот формат указывает, что в определенной позиции байта я должен записать 4 байта данных, чтобы обозначить 32-битное значение без знака... в моем тестовом файле это значение 16052 или 0x00003EB4... поэтому я записываю данные в байтовый массив, который будет сохранен следующим образом:
data[index] = 0xB4;
data[index+1] = 0x3E;
data[index+2] = 0x00;
data[index+3] = 0x00;
Вы можете видеть, что данные в формате с прямым порядком байтов, и это правильно... проблема в том, что когда я пытаюсь загрузить эти данные с помощью функции загрузки файлов, Java видит данные в следующем виде:
-76, 62, 0, 0
значение 0xB4 интерпретируется как -76, потому что байты подписаны в java... когда я пытаюсь перекомпоновать эти 4 байта в одно 32-битное значение, используя следующий код, значение заканчивается как -76...
value = data[index+3];
value <<= 8;
value |= data[index+2];
value <<= 8;
value |= data[index+1];
value <<= 8;
value |= data[index];
Это должно сделать следующее: установить значение 0x00 (байт старшего разряда), сдвинуть 8 бит влево или 0x00 в младшие 8 бит, сдвинуть 8 бит влево или 0x3E в младшие 8 бит, сдвинуть 8 бит влево или 0xB4 (младший байт) на младшие 8 бит.
Это должно привести к значению 0x00003EB4... с которого я и начал... однако по какой-то причине я не могу понять, что оно дает мне значение -76 после этой операции.
Я убежден, что это связано с интерпретацией Java байта 0xB4 как значения -76, которое портит побитовую операцию ИЛИ...
Мой вопрос: что я должен сделать, чтобы обойти это?
Спасибо.
1 ответ
Когда вы загружаете байты, они подписаны. Когда они приводятся к целым числам, они расширяются знаком. Чтобы решить эту проблему, вы можете выполнить побитовое И с 0xFF, чтобы взять только 8 младших бит целого числа со знаком.
В твоем случае value |= (data[index+i])
должен стать value |= (data[index+i] & 0xFF)
(где i
заменяется смещениями индекса, которые у вас есть).