|
|
|

| | | | | | | | |  |
 | 
 | Code source : unité LRJ_FileMapped |  |

|  |
 | |  |

|
Description : cette unité contient les objets suivants :
- LRJ_TMemoryShared contient des méthodes permettant de faciliter la lecture ou l'écriture dans
la mémoire partagée.
- LRJ_TFileMapped permet de créer et utiliser de la mémoire partagée entre plusieurs
processus. La mémoire peut être sauvegarder dans un fichier et recharger automatiquement
lors de la réouverture de la mémoire.
L'unité est livrée avec une application de démonstration (
voir description plus loin
) qui utilise les fonctionnalités des
objets contenus dans l'unité. Les codes de l'application
sont livrés avec l'unité pour illustrer comment utiliser les objets de
cette unité. L'application de démonstration utilise l'unité
LRJ_WindowsPlus non livrée
avec l'application mais téléchargeable gratuitement sur ce site.
L'unité LRJ_FileMapped met en
oeuvre les fonctions de Windows suivantes :
|
|
CloseHandle
CreateDirectory
CreateFile
CreateFileMapping
FlushViewOfFile
GetDiskFreeSpace
GetFileAttributes
GetFileSize
MapViewFile
OpenFileMapping
UnmapViewOfFile
WriteFile
|
Déclarations publiques de l'unité
I
Télécharger l'application de démonstration
I
Exemples d'utilisations
Utilise les unités : Windows, Classes et SysUtils.
Version : 1 du 07.03.2004
Auteur : Laurent Hède
Copyright : LorenJo
Nombre de lignes : 779
Réalisée sous : Delphi 6
Systèmes compatibles : NT4, 2000, XP, Vista, serveurs
Prix : 179.00 € H.T.
Déclarations publiques de l'unité :
unit LRJ_FileMapped;
interface
uses
Windows,
classes,
SysUtils;
type
LRJ_TFileMapped = class;
// On organise dans cet objet que l'on n'est pas obligé d'utiliser lecture ou écrire de type définis
// dans la vue. Selon le contexte, il peut être plus efficace de transtyper le pointeur sur la vue directement
// sans passer par cet objet.
LRJ_TMemoryShared = class(TObject)
......
constructor Create(const AParent : LRJ_TFileMapped);
procedure ResetPosition; // remet position à zéro
function IfOpen: boolean;
procedure seek(const AOffset: integer);
procedure WriteBasic(const ABuffer: pointer; const ACount: Longword);
procedure WriteInteger(const AInteger: integer);
procedure WriteLongword(const ALongword: Longword);
procedure WriteByte(const AByte: byte);
procedure WriteTexte(const ATexte: string);
procedure WriteBoolean(const ABool: Boolean);
procedure WriteTStrings(const AStrList: TStrings);
function ReadBasic(const ABuffer: pointer; const ACount: Longword): boolean;
function ReadInteger: integer;
function ReadLongword: Longword;
function ReadByte: Byte;
function ReadTexte: string;
function ReadBoolean: boolean;
procedure ReadTStrings(const AStrList: TStrings);
end;//-----------FIN--------------------------
//------------OBJET----------------------------
TAnte_FilMap_Base = class(TObject)
...........
procedure SetName(const AName: string);
end;//-----------FIN--------------------------
// Si un fichier sur le disque a été créé, nous le détruisons à la sortie de cet objet en standard sauf si
// on utilise Ecrire_IfFileSharedConserveEnPermanenceSurDisk(true) . Par contre, si la vue
// a été mappéé par d'autres processus, la destruction du fichier sur le disque peut prendre un certain temps, donc la sortie
// de cet objet peut aussi prendre un certain temps.
// Enfin, il est intéressant de créer un fichier sur le disque uniquement si on veut le récupérer à la prochaine réouverture.
//------------OBJET----------------------------
TAnte_FilMap_File = class(TAnte_FilMap_Base)
...........
procedure SetFileName(const Aname: string);
procedure SetDesiredSize(const ASize: DWORD);// il faut définir une taille avant d'ouvrir la mémoire. Cette taille
// n'est plus modifiable après ouverture de la mémoire.
procedure SetIfFileSharedConserveEnPermanenceSurDisk(const ABool: boolean);
procedure SetSecurityAttributes(const APointer: PSecurityAttributes);
procedure CreateFile; //If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a mapping object
//size in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. In this case, CreateFileMapping
//creates a file-mapping object of the specified size backed by the operating-system paging file
//rather than by a named file in the file system. (dixit la doc...)
//Pour notre part, si on n'utilise pas CreateFile, le fichier sera créé en mémoire. Si on utilise
// createfile, il faut renseigné filename avant.
procedure Flush; // copie la MapView dans le fichier alors que la vue est encore ouverte. Si on n'utilise pas
// Flush, la view est copiée sur le disque lorsque l'on unmap la vue.
procedure ClearFichierDisk;
function GetFileSize: Longword;
function GetDesiredSize: DWORD;
end;//-----------FIN--------------------------
// pour écrire et lire, utiliser FileMapCreate. Pour lire simplement un fichier mappé créé ailleurs, utiliser
// plutôt FileMapOpen. Dans ce cas, si l'ouverture échoue, cela signifie que la première instance n'a pas été créée.
// Par contre, une fois ouverte par FileMapCreate ou FileMapOpen, la mémoire reste utilisable dans toutes les instances
// et subsiste tant qu'il y a une instance qui la garde ouverte.
//------------OBJET----------------------------
TAnte_FilMap_OpenCreate = class(TAnte_FilMap_File)
...........
procedure SetIfCannotCreateMoreOneFileMap(const Abool: boolean);
procedure FileMapCreate(const AFilePermis: DWORD = Cst_FileMap_FileCreateAccesDroits); virtual;
procedure FileMapOpen(const AFileMapAcces: DWORD = FILE_MAP_ALL_ACCESS); virtual;
procedure FileMapClose; virtual;
function IfOpen: boolean;
end;//-----------FIN--------------------------
//------------OBJET----------------------------
TAnte_FilMap_MapView = class(TAnte_FilMap_OpenCreate)
...........
procedure MapViewFile(const AAccesFlag: DWORD = FILE_MAP_ALL_ACCESS);
procedure UnMapViewFile; virtual;
function ReadMapView(const AAccesFlag: DWORD = FILE_MAP_ALL_ACCESS): pointer; virtual;
function ReadMapViewTyped(const AAccesFlag: DWORD = FILE_MAP_ALL_ACCESS): LRJ_TMemoryShared; virtual; // Objet capsule qu'il ne faut
// pas détruire à l'endroit où on a appelé cette function. La destruction ce cet objet
// est géré par LRJ_TFileMapped (le parent)
end;//-----------FIN--------------------------
LRJ_TFileMapped = class(TAnte_FilMap_MapView);
|
Application de démonstration

L'application de démonstration permet d'échanger des informations entre plusieurs instances
de cette application. Pour vérifier le fonctionnement de la mémoire partagée, il faut donc ouvrir
plusieurs instances de cette application.
Avant d'utiliser la mémoire partagée, il faut décider si elle sera sauvegardée sur le disque.
Si oui, les dernières informations mises en mémoire
par le bouton Write seront rechargées dans les onglets lorsque l'on re-coche "Fichier conservé sur le disque".
Comme il faut définir la taille de la mémoire partagée avant de la créer et que l'on ne peut plus
modifier cette taille pendant l'utilisation, il faut définir une taille suffisante pour contenir
les informations que l'on veut échanger (onglet Texte et Enregistrement variable) avant d'utiliser
la mémoire partagée (par Write ou Read). Pour un enregistrement fixe, comme on connaît la
taille de la mémoire nécessaire avant utilisation, il n'est pas nécessaire de renseigner
cette donnée. Enfin,
lorsque l'on veut écrire dans la mémoire partagée, il faut cliquer sur Write et lorsque l'on veut
lire la mémoire partagée, il faut cliquer sur Read. Lorsque l'on clique sur Read, le ou les champs
sont rechargés avec les dernières informations entrées en mémoire par le dernier click sur Write
de n'importe laquelle des instances de l'application. Lorsque l'on clique sur Write dans une
instance de l'application, nous broadcastons un message Windows pour que les autres instances
se rechargent. On pourrait réaliser cela plus
finement, mais ce n'est pas l'objet de cette application de démonstration.
Le paramétrage de l'application de démonstration est aussi partagé entre les instances de l'application
par de la mémoire partagée. Donc, lorsque l'on lance une nouvelle instance après avoir entré
des réglages dans l'une des instances précédemment ouvertes, la nouvelle instance contient les réglages
entrés dans les précédentes instances.
L'onglet "Texte" permet d'échanger un texte entre les instances de cette application. Entrer un texte
dans le mémo, puis cliquer sur Write. Dans les autres instances de l'application, le texte est
rechargé.
L'onglet "Enregistrement fixe' contient des enregistrements de taille fixe. Lorsque l'on modifie
un ou plusieurs champs et que l'on clique sur Write, les informations sont rechargées dans les
autres instances de l'application.
L'onglet "Enregistrement variable" contient plusieurs champs de taille variable. De même que
pour les autres onglets, on charge la mémoire par les dernières informations entrées
dans les champs en cliquant sur Write et les autres instances ouvertes de l'application sont
rafraîchies.
Les différents onglets servent à montrer dans le code de l'application de démonstration comment
entrer en mémoire les différents types de champ selon le contexte.
|
|
 |
 | |  |
|
|