Есть сервер, который по команде присылает некоторое количество байт. Объём данных заранее известен - 280 Кбайт. Данные передаются через Wi-Fi сеть по TCP/IP соединению. Используется собственный протокол, который никак не отображает кол-во передаваемой информации. Вся ̶п̶р̶о̶б̶л̶е̶м̶а̶ особенность сервера в том, что он открывает поток (stream) и передает информацию фреймами разного размера. Размер каждого фрейма может колебаться в пределах от 10 до 2048 байт. Он будет передавать фреймы, пока не передаст весь объем данных (280 Кбайт). Другими словами, при приёме данных на Android-устройстве я никак не могу определить объем получаемых данных в потоке, соответственно, не могу разместить все данные в правильном виде.
Вопрос: Как правильно реализовать приём данных при таких "особенностях"?
Возможное решение: Я решил попробовать создать массив размером 2048 (максимально возможный размер фрейма) байт и записывать каждый новый фрейм в этот массив:
DataInputStream din = new DataInputStream(socket.getInputStream());
byte[] buffer = new byte[2048];
din.read(buffer);
Далее данные из моего buffer массива я пробовал помещать в коллекцию ArrayList, однако здесь возникла другая проблема: как определить, где закончились нужные данные, которые я сохранил в массив buffer?
Так как вы заранее знаете объём передаваемых данных, то имеет смысл создать один большой массив (если полученные данные вам нужны целиком), после чего записывать в него блоками считанные байты.
Определить количество считанных в буфер байтов можно по числу, возвращаемому методом read.
Привязывать сюда списки - лишняя трата памяти и лишние неудобства (придётся ведь ещё для каждого считанного "куска" хранить его реальный размер).
Схематичный код чтения данных блоками и запись в результирующий массив:
public byte[] read(Socket socket) throws IOException
{
byte[] array = new byte[280 * 1024];
int arrayPointer = 0;
DataInputStream din = new DataInputStream(socket.getInputStream());
byte[] buffer = new byte[2048];
int readCount;
while ((readCount = din.read(buffer)) != -1)
{
System.arraycopy(buffer, 0, array, arrayPointer, readCount);
arrayPointer += readCount;
}
return array;
}
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости