Подтвердить что ты не робот

Java-создание байтового массива, размер которого представлен длинным

Я пытаюсь создать массив байтов, размер которого имеет тип long. Например, подумайте об этом как:

long x = _________;
byte[] b = new byte[x]; 

По-видимому, вы можете указать только int для размера массива байтов.

Прежде чем кто-нибудь спросит, зачем мне нужен массив байтов настолько большой, я скажу, что мне нужно инкапсулировать данные форматов сообщений, которые я не пишу, и один из этих типов сообщений имеет длину unsigned int (long в Java).

Есть ли способ создать этот массив байтов?

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

4b9b3361

Ответ 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. Это будет медленнее, но гораздо менее тяжело в памяти.

Это когда вы не можете извлечь то, что вам нужно во время первоначального сканирования ввода.