Question

Lorsque vous utilisez des fichiers mappés en mémoire, il semble que ce soit en lecture seule ou en écriture seule. Je veux dire par là que vous ne pouvez pas:

      
  • en avez un ouvert pour l'écriture et décide plus tard de ne pas le sauvegarder   
  • ouvert pour la lecture, puis décide de le sauvegarder

Notre application utilise un fichier mappé en mémoire inscriptible pour enregistrer les fichiers de données, mais comme l'utilisateur peut vouloir quitter sans enregistrer les modifications, nous devons utiliser un fichier temporaire qu'il modifie réellement. Lorsque l'utilisateur choisit d'enregistrer les modifications, le fichier d'origine est écrasé par le fichier temporaire afin qu'il contienne les dernières modifications. Cela est fastidieux, car les fichiers peuvent être très volumineux (> 1 Go) et leur copie prend beaucoup de temps.

J'ai essayé de nombreuses combinaisons d'indicateurs utilisés pour créer le mappage de fichiers, mais aucune ne semble offrir la possibilité d'économiser à la demande. Quelqu'un peut-il confirmer que c'est le cas? Notre application est écrite en Delphi, mais elle utilise l’API Windows standard pour créer le mappage, dans notre cas

.
FMapHandle := CreateFileMapping(FFileHandle, nil, PAGE_READWRITE, 0, 2 * 65536, nil);
FBasePointer := MapViewOfFile(FileMapHandle, FILE_MAP_WRITE, FileOffsetHigh,
FileOffsetLow, NumBytes);
Était-ce utile?

La solution

Je ne pense pas que vous puissiez. Je veux dire par là que vous pouvez le pouvoir, mais cela n’a aucun sens pour moi: -)

L'intérêt d'un fichier mappé en mémoire est qu'il s'agit d'une fenêtre sur le fichier réel. Si vous ne souhaitez pas que les modifications soient reflétées dans le fichier, vous devrez probablement faire quelque chose comme grouper les modifications dans une structure de données (par exemple, un tableau d'adresses de base, de taille et de données) et les appliquer lors de la sauvegarde.

Dans ce cas, vous n'avez pas besoin du fichier mappé en mémoire, il vous suffit de lire et de gérer les morceaux que vous souhaitez modifier (verrouillez d'abord le fichier s'il existe un risque d'accès multi-utilisateur). ).

Mise à jour:

Avez-vous pensé à la possibilité, lors d’une sauvegarde, de supprimer le fichier original et de renommer simplement le fichier temporaire en nom de fichier original? Cela sera probablement beaucoup plus rapide que de copier 1G de données temporaires en données originales. De cette façon, si vous ne voulez pas le sauvegarder, supprimez simplement le fichier temporaire et conservez le fichier d'origine.

Vous devrez toujours copier les données d'origine dans le fichier temporaire lors du chargement, mais vous ne serez pas obligé de les copier (que vous les sauvegardiez ou non) - cela réduirait de moitié le temps pris.

Autres conseils

Possible, mais non trivial.

Vous devez comprendre les bases de la mémoire mappée et la différence entre les trois modes de fichiers mappés en mémoire. Mettez de côté une partie de votre espace d'adressage virtuel et créez une entrée de mappage dans une table interne. Aucune RAM physique n'est initialement allouée. Par conséquent, lorsque vous essayez d'accéder à la mémoire, les erreurs de la CPU et le système d'exploitation doivent être corrigés. Pour ce faire, il copie le contenu du fichier dans la RAM et mappe la RAM sur votre processus, à l’adresse défaillante.

Maintenant, la différence entre les trois modes réside dans la manière dont les descripteurs sont définis sur les pages mappées. Dans tous les cas, vous obtenez un accès en lecture sur les pages. (Le premier mode). Toutefois, si vous demandez un accès en écriture et que vous y écrivez par la suite, lors de votre première écriture, la page est marquée comme inscriptible et sale. Il peut ensuite être écrit dans le fichier d'origine, à la discrétion du système d'exploitation (mode Second). Enfin, il est possible d’obtenir une sémantique de copie sur écriture. Vous commencez toujours avec uniquement un accès en lecture à la page en mémoire. Lorsque vous écrivez dessus, le processeur est toujours défaillant et le système d'exploitation doit le réparer. Avec la copie en écriture, cette correction est effectuée en définissant le magasin de sauvegarde de la page modifiée dans le fichier de page, au lieu du fichier mappé d'origine.

Donc, dans votre cas, vous souhaitez utiliser le mode copie sur écriture. Si l'utilisateur décide de rejeter les modifications, pas de problème. Vous supprimez simplement le mappage de mémoire. Toutes les pages modifiées en mémoire et sauvegardées par le fichier de page sont également ignorées.

Si l'utilisateur décide de sauvegarder, la tâche sera un peu plus difficile. Vous devez maintenant déterminer quelles parties du fichier ont été modifiées. Ces modifications sont en mémoire et vous devez les réappliquer dans le fichier source. Vous pouvez le faire avec les gardes de page . Ainsi, lorsque l'utilisateur décide de sauvegarder, copie toutes les pages modifiées dans un bloc de mémoire séparé, remappe le fichier (non modifié) en écriture et applique les modifications.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top