Pregunta

Cuando se utilizan archivos mapeados en memoria, parece que es de solo lectura o de solo escritura. Con esto quiero decir que no puedes:

      
  • tenga uno abierto para escribir y luego decida no guardarlo   
  • tiene abierto abierto para leer, y luego decide guardarlo

Nuestra aplicación utiliza un archivo mapeado en memoria grabable para guardar archivos de datos, pero dado que el usuario puede querer salir sin guardar los cambios, tenemos que usar un archivo temporal que el usuario realmente edita. Cuando el usuario opta por guardar los cambios, el archivo original se sobrescribe con el archivo temporal para que tenga los últimos cambios. Esto es engorroso porque los archivos pueden ser muy grandes (> 1GB) y toma mucho tiempo copiarlos.

He probado muchas combinaciones de los indicadores utilizados para crear la asignación de archivos, pero ninguno parece permitir la flexibilidad de ahorrar a pedido. ¿Alguien puede confirmar que este es el caso? Nuestra aplicación está escrita en Delphi, pero utiliza la API estándar de Windows para crear el mapeo, en nuestro caso

FMapHandle := CreateFileMapping(FFileHandle, nil, PAGE_READWRITE, 0, 2 * 65536, nil);
FBasePointer := MapViewOfFile(FileMapHandle, FILE_MAP_WRITE, FileOffsetHigh,
FileOffsetLow, NumBytes);
¿Fue útil?

Solución

No creo que puedas. Con eso quiero decir que puede ser capaz de hacerlo, pero no tiene ningún sentido para mí :-)

El punto completo de un archivo mapeado en memoria es que es una ventana al archivo real. Si no cambia los cambios reflejados en el archivo, probablemente tendrá que hacer algo como agrupar los cambios en una estructura de datos (por ejemplo, una matriz de dirección base, tamaño y datos) y aplicarlos al guardar.

En cuyo caso, en realidad no necesitaría el archivo mapeado de memoria, solo lea y mantenga los fragmentos que desea cambiar (bloquee el archivo primero si existe la posibilidad de acceso multiusuario) ).

Update:

¿Ha pensado en la posibilidad de, al guardar, eliminar el archivo original y simplemente renombrar el archivo temporal al nombre del archivo original? Es probable que sea mucho más rápido que copiar 1G de datos de temporal a original. De esa manera, si no desea guardarlo, simplemente elimine el archivo temporal y conserve el original.

Todavía tendrá que copiar los datos originales en el archivo temporal al cargar, pero no tendrá que copiar los datos temporales (ya sea que los guarde o no), eso reduciría a la mitad el tiempo necesario.

Otros consejos

Posible, pero no trivial.

Debe comprender los conceptos básicos de mapeo de memoria y la diferencia entre los tres modos de archivos mapeados de memoria. Ambos reservan una parte de su espacio de direcciones virtuales y crean una entrada de mapeo en una tabla interna. No se asigna RAM física inicialmente. Por lo tanto, cuando intenta acceder a la memoria, la CPU falla y el sistema operativo tiene que arreglar. Lo hace copiando el contenido del archivo a la RAM y asignando la RAM a su proceso, en la dirección con errores.

Ahora, la diferencia entre los tres modos es cómo se configuran los descriptores en las páginas asignadas. En todos los casos, obtienes acceso de lectura en las páginas. (El primer modo). Sin embargo, si solicita acceso de escritura y posteriormente le escribe, en su primera escritura la página está marcada como grabable y sucia. Luego se puede volver a escribir en el archivo original, a discreción del sistema operativo (segundo modo). Finalmente, es posible obtener una semántica de copia en escritura. Todavía comienza con solo acceso de lectura a la página en la memoria. Cuando le escribes, la CPU todavía falla y el sistema operativo necesita repararlo. Con la copia en escritura, esa reparación se realiza configurando el almacén de respaldo de la página modificada en el archivo de página, en lugar del archivo mapeado original.

Entonces, en su caso, desea utilizar el modo de copia en escritura. Si el usuario decide descartar las modificaciones, no hay problema. Simplemente descarta la asignación de memoria. Todas las páginas que se modificaron en la memoria y que estaban respaldadas por el archivo de página también se descartan.

Si el usuario decide guardar, tiene una tarea un poco más difícil. Ahora debe averiguar qué partes del archivo han cambiado. Esos cambios están en la memoria y debe volver a aplicarlos al archivo de origen. Puede hacerlo con Protectores de página . Por lo tanto, cuando el usuario decida guardar, copie todas las páginas modificadas en un bloque de memoria separado, vuelva a asignar el archivo (sin cambios) para escribir y aplique los cambios.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top