Позвольте мне дать упрощенную версию того, что я пробовал. У меня есть файловый актив, который содержит необработанный массив чисел (всего N чисел, каждое из которых имеет ширину 4 байта). Я делаю InputStream
с помощью AssetManager
и пытаюсь передать все данные в прямой ByteBuffer
:
try (InputStream inputStream = assetsManager.open(assetFileName)) {
int size = inputStream.available();
assert size % 4 == 0;
ByteBuffer bytes = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
inputStream.read(bytes.array());
}
Я думал, что это должно работать нормально, но я столкнулся с некоторым странным поведением моей программы, которое заставило меня думать, что загрузка данных в конце концов была неправильной, и действительно, после некоторой отладки первого содержимого внутри bytes
и сравнения его с содержимое файла в программе просмотра HEX. Я обнаружил, что этот подход не считывает первые 4 байта, т. е. содержимое bytes
начинается с моего второго числа шириной 4 байта. Признаюсь, я не проверял, что содержится в конце bytes
, но будем считать, что это просто нули.
Затем я прибегнул к другому подходу, и он полностью и правильно считывает все байты (но это немного уродливо, и я бы хотел этого избежать):
try (InputStream inputStream = assetsManager.open(assetFileName) {
int size = inputStream.available();
byte[] bytesArray = new byte[size];
inputStream.read(bytesArray, 0, size);
ByteBuffer bytes = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
bytes.put(bytesArray);
bytes.rewind();
}
Я действительно новичок в разработке как Java, так и Android, поэтому я спрашиваю, является ли это ошибкой на стороне платформы или есть что-то в InputStream
/ AssetManager.open(...)
, с чем мне нужно обращаться более осторожно, чтобы добиться правильного чтения данных?
Я изучил этот вопрос, который звучит похоже, но он касается С#: NetworkStream обрезает первые 4 байта при чтении
Это навело меня на мысль, что я должен также читать данные кусками и помещать их в ByteStream
один за другим, но мои файлы не большие (менее 16 МБ) и при чтении явно нет гонки данных, поэтому я думаю, что inputStream.read(bytes.array());
не должен подводить странно...
ByteOrder.nativeOrder())
Какой порядок байтов может быть в буфере? Байт есть байт, я бы сказал. - person blackapps   schedule 23.06.2021inputStream.read(bytes.array());
Будет ли один вызов читать 16 МБ? Я думаю.int nread = inputStream.read(bytes.array());
Та же проблема сinputStream.read(bytes, 0, size);
- person blackapps   schedule 23.06.2021ByteOrder.nativeOrder()
- это то, что я нашел в примере OpenGL для Android, не особо задумывался об этом, но отлично работает, когда эти двоичные данные используются для передачи на графический процессор для OpenGL. - person Alexey Larionov   schedule 23.06.2021byte[] bytesArray
Первые четыре байта в шестнадцатеричном формате? - person blackapps   schedule 23.06.2021(yet it's kind of ugly and I'd like to avoid it):
Нет ничего уродливого. Но вы должны проверить возвращаемое значение .read(). - person blackapps   schedule 23.06.20213E 79 0C 3F 49 BB 61 3E ...
- это то, как начинается мой файл,49 BB 61 3E ...
- это то, что я получаю - person Alexey Larionov   schedule 23.06.2021byte[]
, затем какByteBuffer
- person Alexey Larionov   schedule 23.06.202149 BB 61 3E ... is what I get –
??? Не понимаю. Вы сказали, что все прошло нормально, если вы использовали этот массив. - person blackapps   schedule 23.06.2021byte[]
все в порядке, но при прямом чтении вByteBuffer
я теряю первые 4 байта - person Alexey Larionov   schedule 23.06.2021ByteBuffer
не теряло 4 байта, и поэтому я задал этот вопрос. - person Alexey Larionov   schedule 23.06.2021