RandomAccessFile с поддержкой помимо Long?

В настоящее время я использую экземпляр RandomAccessFile для управления некоторыми данными в памяти, но размер моего экземпляра RandomAccessFile превышает 2^64 байта, поэтому я не могу использовать такие методы, как seek() и write(), поскольку они используют Long и не могут управлять адресом. пространство больше, чем 2 ^ 64. Итак, что мне делать? Есть ли что-то еще, что я могу использовать, что поддерживает адресное пространство за пределами 2 ^ 64?

РЕДАКТИРОВАТЬ: Причина задать этот вопрос:

У меня есть структура данных Tree, которая теоретически может иметь до 2 ^ 128 узлов, и я хочу сохранить это дерево в файле. Каждый узел имеет данные размером примерно 6 байт. Поэтому мне интересно, как я буду хранить это дерево в файле.


person Ahmad    schedule 02.08.2017    source источник
comment
Подождите, вы используете файл для управления данными в памяти, и вам нужно управлять более чем 8 миллионами терабайт данных?   -  person JB Nizet    schedule 02.08.2017
comment
Кажется маловероятным, что ваш файл имеет больше байтов, чем максимальный размер long.   -  person DwB    schedule 02.08.2017
comment
В Java нет даже примитивного типа, подходящего для записи смещений в файл, пока вы описываете. Тем не менее, может быть сторонняя библиотека, которая может обрабатывать такие огромные файлы (я не знаю), но рекомендации по программному обеспечению здесь не по теме. Как призывали другие, убедитесь, что это действительно проблема, с которой вы столкнулись. Проблема файлов, превышающих 4 ГБ или даже 2 ГБ — размер C long во многих реализациях C — реальна и важна, но я впервые слышу о файле, превышающем размер 9EB.   -  person John Bollinger    schedule 03.08.2017
comment
Кажется маловероятным, что человечество когда-либо создавало один файл размером более 2^64 байт. Ваше дерево размером 2^128 * 6 байт превышает общую емкость хранилища данных, доступную в настоящее время на Земле, во много миллиардов раз.   -  person Boann    schedule 03.08.2017
comment
Добавил уточнение выше...   -  person Ahmad    schedule 03.08.2017
comment
Это дерево для хранения диапазонов IPv6...   -  person Ahmad    schedule 03.08.2017
comment
Если вашему алгоритму требуется больше памяти, создайте новый. 3-4 года назад общая потребность Google+Facebook в хранении была меньше. См. таблицу с иллюстративными размерами данных на en.m.wikipedia.org/wiki/Orders_of_magnitude_( данные)   -  person tevemadar    schedule 03.08.2017


Ответы (5)


Неправильный ответ, но вы уверены, что ваш файл действительно такой большой?

Из документации для Long.MAX_VALUE:

Константа, содержащая максимальное значение, которое может иметь тип long, 2^63-1.

Из документации для RandomAccessFile.length( ):

длина этого файла, измеренная в байтах.

Вы знаете, сколько байтов 2 ^ 63-1? Вернее, 9 223 372 036 854 775 807 байт?

9,223,372,036,854,775,807 B
9,223,372,036,854,775    KB
9,223,372,036,854        MB
9,223,372,036            GB
9,223,372                TB
9,223                    PB
9                        EB

Если я правильно подсчитал, вам потребуется постоянная скорость записи около 272 ГБ/с в течение 1 года.

Хотя это отличный вопрос, на который я хотел бы увидеть ответ, я очень сомневаюсь, что у вас есть один файл размером 9EB, если ОС вообще будет поддерживать это.

изменить

Вот некоторые ограничения файловой системы и, к моему большому удивлению, NTFS будет фактически поддерживать отдельные файлы до 16EiB, однако это только один из немногих в списке, которые его поддерживают.


Если вам АБСОЛЮТНО необходимо получить доступ к файлу размером более 9EiB, похоже, вам может понадобиться создать собственную версию RandomAccessFile, используя BigInteger, где другой использует long. Это может дать вам до (2 ^ 32) ^ Integer.MAX_VALUE байт.

person Matt Clark    schedule 02.08.2017
comment
NTFS поддерживает файлы размером до 16 EB, поскольку они сохраняют размер как беззнаковое 64-битное значение, тогда как long в Java является знаковым 64-битным значением. Тем не менее, даже NTFS не выходит за рамки 64-битных размеров, потому что нет устройства хранения, которое могло бы хранить такие файлы. - person Boann; 03.08.2017
comment
Игнорируя очевидное в отношении памяти и хранилища, @MattClark прав. Единственный ответ, который я вижу, - свернуть свой собственный с помощью BigInteger. - person Dakoda; 07.08.2017
comment
Мэтт, почему ты добавил награду к вопросу, на который ответил? Просто любопытно - person Carlos Bribiescas; 10.08.2017
comment
Потому что, как я сказал в своем ответе, это не совсем правильный ответ на вопрос. Поскольку это маловероятный вопрос, было бы интересно увидеть реальный, работающий ответ. - person Matt Clark; 10.08.2017
comment
ИМО, это было бы значительно переработано, поскольку нет аппаратного обеспечения для его использования... - person Carlos Bribiescas; 10.08.2017
comment
Это больше памяти, чем у LMG :D - person eliaspr; 11.08.2017
comment
Да, это 18,4467441 экзабайт, что очень много. - person ACV; 12.08.2017

Я полагаю, что ваш вопрос связан с этим требованием: «Есть ли что-то еще, что я могу использовать, что поддерживает адресное пространство за его пределами». Другими словами, вы хотите получить доступ к памяти по адресу, и ваш адрес может быть большим.

Конечно, вы не должны выделять файл размером 2^128 * 6 байт, даже если бы это было возможно в наши дни, это было бы слишком дорого. Типичный подход здесь состоит в том, чтобы разделить хранилище на более мелкие части и адресовать их соответствующим образом. Например

write(partition, address, node);
node = read(partition, address);

Как вы сказали, вы должны хранить адреса IPv6. Для хранения IPv6 и быстрого поиска по нему достаточно иметь таблицу с 8 столбцами и индексами для каждой части адреса ipv6. Или вы можете хранить информацию в древовидной иерархии, например:

  • 0000
    • 0000
      • 0000
        • etc
    • 0001
      • 0000
        • etc

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

ОБНОВИТЬ

Хочу отметить, что на самом деле в Java есть приватный API (Oracle JDK, а не OpenJDK), который может дать вам возможность обрабатывать файлы больше 2 Гб, но он приватный, вообще не является частью публичного API, так что я бы не стал описывать его здесь, без просьб. Вы можете найти его непосредственно в sun.nio.ch.FileChannelImpl (приватные методы map0, unmap0).

person egorlitvinenko    schedule 09.08.2017

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

Итак, поскольку основная проблема заключается в аппаратных ограничениях одной машины, решением будет использование распределенной вычислительной среды, которая позволит вам масштабироваться настолько, насколько это необходимо. Я предлагаю использовать https://ignite.apache.org/, так как он невероятно гибкий и имеет довольно достойную поддержку. здесь при переполнении стека.

Если посмотреть на это с другой точки зрения, вы хотите хранить IP-адреса IPv6. На теоретическом уровне вам понадобится 2 ^ 64 адреса. На практическом уровне, даже если вы попытаетесь проиндексировать каждый IP-адрес сегодня, вы не превысите 2 ^ 32, поскольку это количество адресов IPv4, а мы просто превышаем этот предел.

person Carlos Bribiescas    schedule 09.08.2017
comment
Аппаратные ограничения, безусловно, не должны быть связаны с оперативной памятью, если они реализованы правильно. Из Документов по Java — A random access file behaves like a large array of bytes stored in the file system. При поддержке файловой системой, вы можете открыть дескриптор файла и найти нужное место. Вы не должны загружать весь файл в память. - person Matt Clark; 10.08.2017
comment
Возможно, я неправильно понял, так как думал, что он загрузит это в память. Тот же аргумент применим к пространству на жестком диске, хотя я сомневаюсь, что он (практически) сможет найти одну машину с таким большим дисковым пространством. Практическое решение — распределенные вычисления. Я не буду обновлять свой ответ, потому что я не хочу искать фактически возможный максимальный диск для современного компьютера. :-) - person Carlos Bribiescas; 10.08.2017
comment
Если вы читали мой ответ, это тоже есть. Моя награда заключалась в том, чтобы найти более конкретную реализацию, поскольку мой ответ просто излагал семантику или проблему. :) - person Matt Clark; 10.08.2017
comment
Удаление полностью части об оперативной памяти. Я думаю, что мой ответ является реальным решением, потому что он выходит за рамки академической, теоретической проблемы и дает ему средство / возможность действительно решить свою проблему. Спасибо, что указали, что я неправильно понял вопрос - person Carlos Bribiescas; 10.08.2017

Да, это 18.4467441 эксабайт, что очень много. Вы не можете хранить это в памяти, так как нет ни компьютера, ни даже кластера с такой памятью (ОЗУ).

Конечно, вы можете писать в файлы. Но это обязательно должно быть несколько файлов. Я не думаю, что возможно иметь 1 такой большой файл. И если бы это было возможно, поиски заняли бы часы или дни. Итак, есть 2 подхода:

  1. Разделить на несколько файлов меньшего размера

  2. Используйте «потоки» — читайте немного, обрабатывайте, записывайте и читайте дальше.

person ACV    schedule 11.08.2017
comment
Как уже обсуждалось другой ответ, RandomAccessFile уже основан на файле файловой системы и имеет возможность искать определенную позицию и поток, поэтому нет необходимости или причины загружать его в память. - person Matt Clark; 13.08.2017

Возможно, это глупое наблюдение, но думали ли вы о сериализации? ваша структура данных? В Интернете есть много примеров, я нашел этот простой пример, который вы можете настроить для своего дерева , затем вы можете выполнить преобразование для сохранения данных.

person Damián Rafael Lattenero    schedule 12.08.2017