Java-создание байтового массива, размер которого представлен длинным
Я пытаюсь создать массив байтов, размер которого имеет тип long
. Например, подумайте об этом как:
long x = _________;
byte[] b = new byte[x];
По-видимому, вы можете указать только int
для размера массива байтов.
Прежде чем кто-нибудь спросит, зачем мне нужен массив байтов настолько большой, я скажу, что мне нужно инкапсулировать данные форматов сообщений, которые я не пишу, и один из этих типов сообщений имеет длину unsigned int (long
в Java).
Есть ли способ создать этот массив байтов?
Я думаю, что если это не так, я могу создать выходной поток байтового массива и продолжать кормить его байтами, но я не знаю, существует ли ограничение на размер массива байтов...
Ответы
Ответ 1
(Вероятно, это немного поздно для OP, но он может быть полезен другим)
К сожалению, Java не поддерживает массивы с более чем 2 элементами 31 -1. Максимальное потребление составляет 2 гигабайта пространства для массива byte[]
или 16 гигабайт пространства для массива long[]
.
Хотя это, вероятно, неприменимо в этом случае, если массив будет sparse, вы можете получить используя ассоциативную структуру данных, такую как Map
, чтобы сопоставить каждое используемое смещение с соответствующим значением. Кроме того, Trove обеспечивает более экономичную реализацию памяти для хранения примитивных значений, чем стандартные коллекции Java.
Если массив не разрежен и вам действительно нужен действительно весь блоб в памяти, вам, вероятно, придется использовать двумерную структуру, например. с Map
совпадающими смещениями по модулю 1024 с соответствующим 1024-байтовым массивом. Такой подход может быть более эффективным с точки зрения памяти даже для разреженных массивов, поскольку смежные заполненные ячейки могут использовать одну и ту же запись Map
.
Ответ 2
A byte[]
с размером максимального 32-разрядного целого числа со знаком будет требовать 2 ГБ смежного адресного пространства. Вы не должны пытаться создать такой массив. В противном случае, если размер на самом деле не такой большой (и это просто больший тип), вы можете безопасно применить его к int
и использовать его для создания массива.
Ответ 3
Вероятно, вы должны использовать поток для чтения своих данных, а другой - для его записи. Если вы хотите получить доступ к данным позже в файле, сохраните его. Если вам нужен доступ к чему-то, с которым вы еще не столкнулись, вам нужна двухпроходная система, в которой вы запускаете один раз и сохраняете "материал, который вам понадобится для второго прохода, а затем снова выполняйте".
Составители работают таким образом.
Единственный случай загрузки во всем массиве сразу - если вам приходится неоднократно произвольно обращаться ко многим местоположениям по всему массиву. Если это так, я предлагаю вам загрузить его в несколько байт-массивов, хранящихся в одном классе контейнера.
Класс контейнера будет иметь массив байтовых массивов, но извне все обращения будут казаться смежными. Вы просто попросите байта 49874329128714391837, и ваш класс разделит ваш Long на размер каждого байтового массива, чтобы вычислить, какой массив нужно получить, а затем использовать остаток для определения байта.
Он также может иметь методы для хранения и извлечения "Chunks", которые могут охватывать границы массива байтов, которые потребуют создания временной копии, - но стоимость создания нескольких временных массивов была бы более чем компенсирована фактом что у вас нет зарезервированного места в 2gb, которое, я думаю, может просто разрушить вашу производительность.
Изменить: ps. Если вам действительно нужен случайный доступ и вы не можете использовать потоки, то реализация содержащего класса - очень хорошая идея. Это позволит вам изменить реализацию "на лету" из одного байтового массива в группу байт-массивов в файловую систему без каких-либо изменений в остальной части вашего кода.
Ответ 4
Это не немедленная помощь, а создание массивов с большими размерами (через longs) - это предлагаемое изменение языка для Java 7. Ознакомьтесь с предложениями по проектной монете для получения дополнительной информации
Ответ 5
Один из способов "сохранить" массив - записать его в файл, а затем получить к нему доступ (если вам нужно получить доступ к нему, как массив) с помощью RandomAccessFile. Api для этого файла использует long как индекс в файле вместо int. Это будет медленнее, но гораздо менее тяжело в памяти.
Это когда вы не можете извлечь то, что вам нужно во время первоначального сканирования ввода.