Я читаю двоичный файл как это:
InputStream in = new FileInputStream( file );
byte[] buffer = new byte[1024];
while( ( in.read(buffer ) > -1 ) {
int a = // ???
}
Что я хочу сделать это, чтобы считать до 4 байтов и создать международную стоимость от тех, но, я не знаю, как сделать это.
Я отчасти чувствую, что должен захватить 4 байта за один раз и выполнить одну операцию "байта" (как>> <<>> и FF и материал как этот) для создания нового интервала
Какова идиома для этого?
Править
Ooops это оказывается немного более сложным (для объяснения)
То, что я пытаюсь сделать, читайте, файл (может быть ASCII, двоичный файл, он не имеет значения), и извлеките целые числа, которые он может иметь.
Например, предположите двоичное содержание (в основе 2):
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
Целочисленное представление должно быть 1
, 2
право?:-/1 для первых 32 битов, и 2 для остающихся 32 битов.
11111111 11111111 11111111 11111111
Был бы-1
и
01111111 11111111 11111111 11111111
Был бы Integer.MAX_VALUE ( 2147483647 )
ByteBuffer имеет эту возможность и может работать как с малым, так и с большим порядком байтов.
Рассмотрим следующий пример:
// read the file into a byte array
File file = new File("file.bin");
FileInputStream fis = new FileInputStream(file);
byte [] arr = new byte[(int)file.length()];
fis.read(arr);
// create a byte buffer and wrap the array
ByteBuffer bb = ByteBuffer.wrap(arr);
// if the file uses little endian as apposed to network
// (big endian, Java's native) format,
// then set the byte order of the ByteBuffer
if(use_little_endian)
bb.order(ByteOrder.LITTLE_ENDIAN);
// read your integers using ByteBuffer's getInt().
// four bytes converted into an integer!
System.out.println(bb.getInt());
Надеюсь, это поможет.
Самый простой способ:
RandomAccessFile in = new RandomAccessFile("filename", "r");
int i = in.readInt();
- или -
DataInputStream in = new DataInputStream(new BufferedInputStream(
new FileInputStream("filename")));
int i = in.readInt();
for (int i = 0; i < buffer.length; i++)
{
a = (a << 8) | buffer[i];
if (i % 3 == 0)
{
//a is ready
a = 0;
}
}
просто посмотрите, как реализован DataInputStream.readInt();
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
Вы должны поместить это в функцию, как это:
public static int toInt(byte[] bytes, int offset) {
int ret = 0;
for (int i=0; i<4 && i+offset<bytes.length; i++) {
ret <<= 8;
ret |= (int)bytes[i] & 0xFF;
}
return ret;
}
Пример:
byte[] bytes = new byte[]{-2, -4, -8, -16};
System.out.println(Integer.toBinaryString(toInt(bytes, 0)));
Вывод:
11111110111111001111100011110000
Это позаботится о нехватке байтов и правильной обработке отрицательных значений байтов.
Я не знаю стандартной функции для этого.
Вопросы для рассмотрения:
Эндианальность: различные архитектуры процессоров располагают байты, составляющие int, в разном порядке. В зависимости от того, как вы создаете массив байтов для начала, вы можете столкнуться с этой проблемой; и
Буферизация: если вы возьмете 1024 байта за раз и начнете последовательность с элемента 1022, вы достигнете конца буфера прежде, чем получите 4 байта. Возможно, лучше использовать некоторую форму буферизованного входного потока, который выполняет буферизацию автоматически, так что вы можете просто использовать readByte()
многократно и не беспокоиться об этом в противном случае;
Trailing Buffer: конец ввода может быть неравномерным количеством байт (не кратным 4) в зависимости от источника. Но если вы создаете входные данные с самого начала, и их кратность 4 "гарантирована" (или, по крайней мере, является предварительным условием), вам, возможно, не нужно беспокоиться об этом.
чтобы более подробно остановиться на вопросе буферизации, рассмотрим BufferedInputStream
:
InputStream in = new BufferedInputStream(new FileInputStream(file), 1024);
Теперь у вас есть InputStream
, который автоматически буферизирует 1024 байта за раз, что гораздо менее неудобно. Таким образом, вы можете спокойно читать по 4 байта за раз и не беспокоиться о большом количестве операций ввода-вывода.
Во-вторых, вы также можете использовать DataInputStream
:
InputStream in = new DataInputStream(new BufferedInputStream(
new FileInputStream(file), 1024));
byte b = in.readByte();
или даже:
int i = in.readInt();
и вообще не беспокоиться о построении int
ов.
попробуйте что-нибудь вроде этого:
a = buffer[3];
a = a*256 + buffer[2];
a = a*256 + buffer[1];
a = a*256 + buffer[0];
предполагается, что младший байт идет первым. если первым идет старший байт, возможно, придется поменять индексы местами (с 0 на 3).
в основном для каждого байта, который вы хотите добавить, вы сначала умножаете a на 256 (что равняется сдвигу влево на 8 бит), а затем добавляете новый байт.
Если они уже есть в массиве byte [], вы можете использовать:
int result = ByteBuffer.wrap(bytes).getInt();
источник: здесь