getfilepointer - metodos de la clase randomaccessfile java
RandomAccessFile con soporte más allá de Long? (5)
Actualmente estoy usando una instancia de RandomAccessFile
para administrar algunos datos en memoria, pero el tamaño de mi instancia de RandomAccessFile
es más allá de 2 ^ 64 bytes, por lo que no puedo usar métodos como seek()
y write()
porque usan Long
y no puede administrar un espacio de direcciones mayor que 2 ^ 64. Entonces qué hago ? ¿Hay algo más que pueda usar que admita un espacio de direcciones más allá de 2 ^ 64?
EDITAR: Razón para hacer esta pregunta:
Tengo una estructura de datos de árbol que, en teoría, puede tener hasta 2 ^ 128 nodos, y quiero almacenar este árbol en un archivo. Cada nodo tiene datos que son aproximadamente 6 bytes. Así que me pregunto cómo almacenaré este árbol en el archivo.
Incluso si tuviera el software para hacer tales cosas, sería inutilizable a la escala que sugiere, ya que no existe una sola máquina con tanto espacio en el disco.
Entonces, dado que el problema principal son las limitaciones de hardware de una sola máquina, la solución sería utilizar un marco de computación distribuida que le permita escalar tanto como sea necesario. Sugiero usar https://ignite.apache.org/ ya que es increíblemente flexible y tiene un soporte bastante decente aquí en el desbordamiento de pila.
Desde este punto de vista, desea almacenar las direcciones IP de IPv6. En el nivel teórico, seguro que necesitarás 2 ^ 64 direcciones. En el nivel práctico, incluso si intentara indexar cada IP que hay hoy en día, no pasaría significativamente 2 ^ 32 ya que esa es la cantidad de direcciones IPv4s y solo estamos pasando ese límite.
No es una respuesta correcta, pero ¿está seguro de que su archivo es realmente tan grande?
De los documentos para Long.MAX_VALUE :
Una constante que contiene el valor máximo que puede tener un largo, 2 ^ 63-1.
De los documentos para RandomAccessFile.length() :
La longitud de este archivo, medida en bytes .
¿Sabes cuántos bytes 2 ^ 63-1 es? Más bien, ¿9.223.372.036.854.775.807 bytes?
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
Si las matemáticas fueran correctas, necesitaría una velocidad de escritura constante de aproximadamente 272GB / s durante 1 año .
Si bien esta es una excelente pregunta a la que me gustaría ver una respuesta, dudo mucho que tenga un solo archivo que tenga un tamaño de 9EB, si el sistema operativo lo admite.
editar
Aquí hay algunos límites del sistema de archivos , y para mi sorpresa, NTFS realmente admitirá archivos individuales de hasta 16EiB, sin embargo, es solo uno de los pocos en la lista que sí lo admiten.
Si ABSOLUTAMENTE necesita acceder a un archivo más grande que 9EiB, parece que podría necesitar rodar su propia versión de RandomAccessFile, usando BigInteger donde el otro usa mucho tiempo. Esto podría llevarle hasta (2 ^ 32) ^ Integer.MAX_VALUE
bytes.
Sí, esto es 18.4467441
Exabytes que es mucho. No puede almacenar esto en la memoria ya que no hay computadora ni clúster con dicha memoria (RAM).
Por supuesto que puedes escribir en archivos. Pero estos definitivamente deben ser múltiples archivos. No creo que sea posible tener 1 archivo tan grande. Y si fuera posible, llevaría horas o días buscarlo. Así que hay 2 enfoques:
Dividir en múltiples archivos más pequeños
Use "streams" - lea un poco, procese, escriba y lea a continuación.
Supongo que su pregunta surge de este requisito "¿Hay algo más que pueda usar que admita un espacio de direcciones más allá". En otras palabras, desea acceder a la memoria por dirección, y su dirección podría ser grande.
Por supuesto, no debe asignar un archivo de 2 ^ 128 * 6 bytes, aunque hoy en día sería posible, sería demasiado costoso. El enfoque típico aquí es dividir su almacenamiento en partes más pequeñas y abordarlo en consecuencia. Por ejemplo
write(partition, address, node);
node = read(partition, address);
Como dijiste, debes almacenar las direcciones IPv6. Para almacenar IPv6 y realizar búsquedas rápidas es suficiente tener una tabla con 8 columnas e índices para cada parte de una dirección ipv6. O puede almacenar información en la jerarquía de árbol como:
- 0000
- 0000
- 0000
- etc
- 0000
- 0001
- 0000
- etc
- 0000
- 0000
Que debe asignar en la demanda. Entonces, la verdadera pregunta debería ser cómo organizar su almacenamiento de manera efectiva.
ACTUALIZAR
Quiero señalar que en realidad hay una API privada en Java (Oracle JDK, no OpenJDK), que puede darle la oportunidad de manejar archivos de más de 2 Gb, pero es privada, no es una parte de la API pública. Así que no lo describiría aquí, sin peticiones. Puede encontrarlo directamente en sun.nio.ch.FileChannelImpl (mapm privado, métodos unmap0).
Tal vez sea una observación tonta , pero ¿pensaste en serialize tu estructura de datos? Hay muchos ejemplos en línea; si miro alrededor, encontré este ejemplo simple que podría ajustar a su árbol, luego puede hacer la conversión para almacenar los datos.