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

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

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

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

5 ответов

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

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

Константа, содержащая максимальное значение, которое может иметь длинная, 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 байт.

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

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

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

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

  • 0000
    • 0000
      • 0000
        • так далее
    • 0001
      • 0000
        • так далее

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

ОБНОВИТЬ

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

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

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

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

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

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

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

  1. Разделить на несколько небольших файлов

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

Другие вопросы по тегам