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
- так далее
- 0000
- 0001
- 0000
- так далее
- 0000
- 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 подхода:
Разделить на несколько небольших файлов
Используйте "потоки" - читайте немного, обрабатывайте, пишите и читайте дальше.