Как получить определенные байты из файла, зная смещение и длину?

У меня есть файл, и первые 4 байта файла — это магия, такая как LOL . Как я могу получить эти данные?

Я представлял, что это будет так:

byte[] magic = new byte[4];
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.read(magic, 0, magic.length);
System.out.println(new String(magic));

Выход:

LOL

К сожалению, это не работает для меня. Я не могу найти способ получить конкретные значения.

Кто-нибудь видит способ решить эту проблему?


person user3530525    schedule 06.11.2014    source источник


Ответы (1)


Используйте RandomAccessFile.seek() для позиционирования туда, откуда вы хотите читать, и RandomAccessFile.readFully() для чтения полного массива byte.

byte[] magic = new byte[4];
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(0L);
raf.readFully(magic);
System.out.println(new String(magic));

Проблема с вашим кодом в том, что когда вы создаете файл в режиме чтения-записи, скорее всего, указатель файла указывает на конец файла. Используйте метод seek() для позиционирования.

Также вы можете использовать RandomAccessFile.read(byte[] b, int off, int len) тоже, но смещение и длина соответствуют смещению в массиве, с которого начинается сохранение прочитанных байтов, а длина указывает, сколько байт считывать из файла. Но данные по-прежнему будут считываться из текущей позиции файла, а не из позиции off.

Итак, как только вы вызвали seek(0L);, этот метод чтения также работает:

raf.read(magic, 0, magic.length);

Также обратите внимание, что методы чтения и записи автоматически перемещают текущую позицию, поэтому, например, поиск 0L, а затем чтение 4 байтов (ваше волшебное слово) приведет к перемещению текущего указателя на 4L. Это означает, что вы можете вызывать методы чтения последовательно без поиска перед каждым чтением, и они будут читать непрерывную часть файла, увеличивающуюся по позиции, они не будут читать с одной и той же позиции.

Последнее примечание:

При создании String из массива byte цитирование из javadoc String(byte[] bytes):

Создает новую строку, декодируя указанный массив байтов, используя кодировку платформы по умолчанию.

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

new String(magic, StandardCharsets.UTF_8);
person icza    schedule 06.11.2014
comment
Работает, большое спасибо. Я никогда не знал, как работала реализация RAF. Спасибо;) Я приму ваш ответ через 7 минут (ограничение stackoverflow). - person user3530525; 07.11.2014
comment
@ user3530525 Нет проблем :) - person icza; 07.11.2014