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

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

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

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

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

4b9b3361

Ответ 1

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

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

Постоянная, имеющая максимальное значение a 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, где другой использует длинный. Это может привести вас к (2 ^ 32) ^ Integer.MAX_VALUE байтам.

Ответ 2

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

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

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

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

  • 0000
    • 0000
      • 0000
        • и т.д.
    • 0001
      • 0000
        • и т.д.

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

ОБНОВЛЕНИЕ

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

Ответ 3

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

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

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

Ответ 4

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

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

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

  • Используйте "потоки" - читайте немного, обрабатывайте, пишите и читайте дальше.

Ответ 5

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