Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MAPPING DE FICHIER ET TSTREAM


Information sur la source

Description

Cette unit contien un simple objet TSream surchargé pour employé le principe du mapping de fichier en mémoire de Windows. Il s'utilise comme un MemoryStream ou un FileSream
 

Source

  • unit MappedFileStream;
  • interface
  • uses
  • Windows,
  • SysUtils,
  • Classes;
  • type
  • TMappedFileStream = class(TStream)
  • private
  • hMapping : THandle; // Handle de l'objet file-mapping
  • FMemory : pByteArray;// Adresse de base du mapping
  • FHandle : THandle; // Handle du fichier ouvert pour le mapping
  • FPosition,
  • FSize : Integer;
  • public
  • // Enregistre les pages modifiées dans le fichier sur le disque
  • procedure Flush;
  • function Read(var Buffer; Count: Longint): Longint; override;
  • function Write(const Buffer; Count: Longint): Longint; override;
  • function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
  • property Memory: pByteArray read FMemory;
  • property Position: Integer read FPosition;
  • property Size : Integer read FSize;
  • property Handle: THandle read FHandle;
  • constructor Create(FileName: string;
  • Mode: Word = fmOpenRead;
  • Rights: Cardinal = fmShareExclusive;
  • Offset: Cardinal = 0;
  • MaxSize: Cardinal = 0);
  • destructor Destroy; override;
  • published
  • { Published declarations }
  • end;
  • implementation
  • procedure TMappedFileStream.Flush;
  • begin
  • FlushViewOfFile(FMemory, 0);
  • end;
  • function TMappedFileStream.Read(var Buffer; Count: Integer): Integer;
  • begin
  • if FPosition + Count > Size then Count := Size - FPosition;
  • move(FMemory[FPosition], Buffer, Count);
  • Result := Count;
  • end;
  • function TMappedFileStream.Write(const Buffer; Count: Longint): Longint;
  • begin
  • if FPosition + Count > Size then Count := Size - FPosition;
  • move(Buffer, FMemory[FPosition], Count);
  • Result := Count;
  • end;
  • function TMappedFileStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
  • begin
  • Case Origin of
  • soBeginning: // Seek from the beginning of the resource. The seek operation moves to a specified position (offset), which must be greater than or equal to zero.
  • if Offset < FSize then FPosition := Offset else raise ERangeError.Create('');
  • soCurrent : // Seek from the current position in the resource. The seek operation moves to an offset from the current position (position + offset). The offset is positive to move forward, negative to move backward.
  • if FPosition + Offset < FSize then FPosition := FPosition + Offset else raise ERangeError.Create('');
  • soEnd : // Seek from the end of the resource. The seek operation moves to an offset from the end of the resource, where the offset is expressed as a negative value because it is moving toward the beginning of the resource.
  • if FSize - Offset >= 0 then FPosition := FSize - Offset else raise ERangeError.Create('');
  • end;
  • result := FPosition;
  • end;
  • constructor TMappedFileStream.Create(FileName: string;
  • Mode: Word = fmOpenRead;
  • Rights: Cardinal = fmShareExclusive;
  • Offset: Cardinal = 0;
  • MaxSize: Cardinal = 0);
  • var
  • dwDA, dwSM, dwCD, flP, dwVA: DWORD;
  • FileInfo: _BY_HANDLE_FILE_INFORMATION;
  • begin
  • // Initialise correctement les attributs de construction du mapping
  • case Mode of
  • fmCreate:
  • begin
  • dwCD := CREATE_ALWAYS;
  • dwDA := GENERIC_WRITE and GENERIC_READ;
  • dwVA := FILE_MAP_WRITE;
  • flP := PAGE_READWRITE;
  • end;
  • fmOpenRead:
  • begin
  • dwCD := OPEN_EXISTING;
  • dwDA := GENERIC_READ;
  • dwVA := FILE_MAP_READ;
  • flP := PAGE_READONLY;
  • end;
  • fmOpenWrite:
  • begin
  • dwCD := TRUNCATE_EXISTING;
  • dwDA := GENERIC_WRITE and GENERIC_READ;
  • dwVA := FILE_MAP_WRITE;
  • flP := PAGE_READWRITE;
  • end;
  • fmOpenReadWrite:
  • begin
  • dwCD := OPEN_EXISTING;
  • dwDA := GENERIC_WRITE and GENERIC_READ;
  • dwVA := FILE_MAP_WRITE;
  • flP := PAGE_READWRITE;
  • end;
  • end;
  • case Rights of
  • fmShareCompat or fmShareExclusive:
  • begin
  • dwSM := 0;
  • end;
  • fmShareDenyWrite:
  • begin
  • dwSM := FILE_SHARE_READ;
  • end;
  • fmShareDenyRead:
  • begin
  • dwSM := FILE_SHARE_WRITE;
  • end;
  • fmShareDenyNone:
  • begin
  • dwSM := FILE_SHARE_READ and FILE_SHARE_WRITE;
  • end;
  • end;
  • // Ouvre le fichier
  • FileName := FileName + #0; // Ajout du zero terminal
  • FHandle := CreateFile(@FileName[1], dwDA, dwSM, nil, dwCD, 0, 0);
  • inherited create;
  • if FHandle = INVALID_HANDLE_VALUE then raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
  • if MaxSize = 0 then begin
  • if not GetFileInformationByHandle(FHandle, FileInfo) then begin
  • CloseHandle(FHandle);
  • raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
  • end;
  • FSize := FileInfo.nFileSizeLow;
  • end else FSize := MaxSize;
  • hMapping := CreateFileMapping(FHandle, nil, flP, 0, FSize, nil);
  • if hMapping = INVALID_HANDLE_VALUE then begin
  • FileClose(FHandle);
  • raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
  • end;
  • FMemory := MapViewOfFile(hMapping, dwVA, 0, 0, FSize);
  • if FMemory = nil then begin
  • FileClose(FHandle);
  • CloseHandle(hMapping);
  • raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
  • end;
  • end;
  • destructor TMappedFileStream.Destroy;
  • begin
  • Flush;
  • UnMapViewOfFile(FMemory);
  • CloseHandle(hMapping);
  • CloseHandle(FHandle);
  • inherited destroy;
  • end;
  • end.
unit MappedFileStream;

interface

uses
  Windows,
  SysUtils,
  Classes;

type
  TMappedFileStream = class(TStream)
  private
    hMapping : THandle;   // Handle de l'objet file-mapping
    FMemory  : pByteArray;// Adresse de base du mapping
    FHandle  : THandle;   // Handle du fichier ouvert pour le mapping
    FPosition,
    FSize    : Integer;
  public
    // Enregistre les pages modifiées dans le fichier sur le disque
    procedure Flush;
    function  Read(var Buffer; Count: Longint): Longint; override;
    function  Write(const Buffer; Count: Longint): Longint; override;
    function  Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
    property  Memory: pByteArray read FMemory;
    property  Position: Integer read FPosition;
    property  Size : Integer read FSize;
    property  Handle: THandle read FHandle;
    constructor Create(FileName: string;
                       Mode: Word = fmOpenRead;
                       Rights: Cardinal = fmShareExclusive;
                       Offset: Cardinal = 0;
                       MaxSize: Cardinal = 0);
    destructor Destroy; override;
  published
    { Published declarations }
  end;

implementation

procedure TMappedFileStream.Flush;
begin
  FlushViewOfFile(FMemory, 0);
end;

function TMappedFileStream.Read(var Buffer; Count: Integer): Integer;
begin
  if FPosition + Count > Size then Count := Size - FPosition;
  move(FMemory[FPosition], Buffer, Count);
  Result := Count;
end;

function TMappedFileStream.Write(const Buffer; Count: Longint): Longint;
begin
  if FPosition + Count > Size then Count := Size - FPosition;
  move(Buffer, FMemory[FPosition], Count);
  Result := Count;
end;

function TMappedFileStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
  Case Origin of
  soBeginning:  // Seek from the beginning of the resource. The seek operation moves to a specified position (offset), which must be greater than or equal to zero.
    if Offset < FSize then FPosition := Offset else raise ERangeError.Create('');
  soCurrent  :  // Seek from the current position in the resource. The seek operation moves to an offset from the current position (position + offset). The offset is positive to move forward, negative to move backward.
    if FPosition + Offset < FSize then FPosition := FPosition + Offset else raise ERangeError.Create('');
  soEnd      :  // Seek from the end of the resource. The seek operation moves to an offset from the end of the resource, where the offset is expressed as a negative value because it is moving toward the beginning of the resource.
    if FSize - Offset >= 0 then FPosition := FSize - Offset else raise ERangeError.Create('');
  end;

  result := FPosition;
end;

constructor TMappedFileStream.Create(FileName: string;
                                     Mode: Word = fmOpenRead;
                                     Rights: Cardinal = fmShareExclusive;
                                     Offset: Cardinal = 0;
                                     MaxSize: Cardinal = 0);
var
    dwDA, dwSM, dwCD, flP, dwVA: DWORD;
    FileInfo: _BY_HANDLE_FILE_INFORMATION;
begin
// Initialise correctement les attributs de construction du mapping
  case Mode of
    fmCreate:
      begin
        dwCD := CREATE_ALWAYS;
        dwDA := GENERIC_WRITE and GENERIC_READ;
        dwVA := FILE_MAP_WRITE;
        flP  := PAGE_READWRITE;
      end;
    fmOpenRead:
      begin
        dwCD := OPEN_EXISTING;
        dwDA := GENERIC_READ;
        dwVA := FILE_MAP_READ;
        flP  := PAGE_READONLY;
      end;
    fmOpenWrite:
      begin
        dwCD := TRUNCATE_EXISTING;
        dwDA := GENERIC_WRITE and GENERIC_READ;
        dwVA := FILE_MAP_WRITE;
        flP  := PAGE_READWRITE;
      end;
    fmOpenReadWrite:
      begin
        dwCD := OPEN_EXISTING;
        dwDA := GENERIC_WRITE and GENERIC_READ;
        dwVA := FILE_MAP_WRITE;
        flP  := PAGE_READWRITE;
      end;
  end;

  case Rights of
    fmShareCompat or fmShareExclusive:
      begin
        dwSM := 0;
      end;
    fmShareDenyWrite:
      begin
        dwSM := FILE_SHARE_READ;
      end;
    fmShareDenyRead:
      begin
        dwSM := FILE_SHARE_WRITE;
      end;
    fmShareDenyNone:
      begin
        dwSM := FILE_SHARE_READ and FILE_SHARE_WRITE;
      end;
  end;

// Ouvre le fichier
  FileName := FileName + #0; // Ajout du zero terminal
  FHandle := CreateFile(@FileName[1], dwDA, dwSM, nil, dwCD, 0, 0);
  inherited create;
  if FHandle = INVALID_HANDLE_VALUE then raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));

  if MaxSize = 0 then begin
    if not GetFileInformationByHandle(FHandle, FileInfo) then begin
       CloseHandle(FHandle);
       raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
    end;
    FSize := FileInfo.nFileSizeLow;
  end else FSize := MaxSize;

  hMapping := CreateFileMapping(FHandle, nil, flP, 0, FSize, nil);
  if hMapping = INVALID_HANDLE_VALUE then begin
    FileClose(FHandle);
    raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
  end;

  FMemory := MapViewOfFile(hMapping, dwVA, 0, 0, FSize);
  if FMemory = nil then begin
    FileClose(FHandle);
    CloseHandle(hMapping);
    raise Exception.Create('Erreur Windows N°' + IntToStr(GetLastError));
  end;

end;

destructor TMappedFileStream.Destroy;
begin
  Flush;
  UnMapViewOfFile(FMemory);
  CloseHandle(hMapping);
  CloseHandle(FHandle);
  inherited destroy;
end;

end.

Commentaires et avis

signaler à un administrateur
Commentaire de Delphiprog le 10/10/2006 20:58:13 administrateur CS

Un petit exemple d'utilisation est toujours le bienvenu voire indispensable.
A première vue, ça a l'air intéressant.

signaler à un administrateur
Commentaire de f0xi le 19/10/2006 16:32:27 administrateur CS

et un zip avec l'unitée source aussi.

signaler à un administrateur
Commentaire de bubulemaster le 08/10/2007 17:07:16

FileName := FileName + #0; // Ajout du zero terminal
FHandle := CreateFile(@FileName[1], dwDA, dwSM, nil, dwCD, 0, 0);

Pourquoi ne pas utiliser PChar :
FHandle := CreateFile(Pchar(FileName), dwDA, dwSM, nil, dwCD, 0, 0);

signaler à un administrateur
Commentaire de /dev/null le 07/01/2008 02:53:00

Sauf si cela a changer, le dump du code compilé en utilisant le transtypage par PChar fait apelle a une fonction qui doit contenir quelque instruction. Une écriture pas super lisible permet de réduire le temps d'éxécution et l'espace mémoire utilisé.
C'est vraie que ce n'est pas l'endroit ou l'optimisation est la mieux placé. Mais ça a fini par devenir une abitude de codage, comme utilisé un index décroisant vers 0 dans mes boucle ^^

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

TNMStrm [ par neodelphi ] Bonjour a tous 8)Voila, j'ai crée d'un coté un TNMStrm, et de l'autre coté un TNMStrmServ. Du coté 1 je cré un filestream, et pi je fait :NMStrm1.Post TNMStrm [ par neodelphi ] bonjour a tous !!!Voila, j'ai crée d'un coté un TNMStrm, et de l'autre coté un TNMStrmServ. Du coté 1 je cré un filestream, et pi je fait :NMStrm1.Pos Transfert images par Stream [ par mattsprings ] Bonjour, je cherche comment transferer des images dans un memorystream à travers le réseau. Je veux envoyer des images venant d'un composant TImage, à Acces rapide à un fichier [ par bgK ] Mon problème est le suivant :Je souhaite rechercher toutes les occurances d'une séquence de 4 octets dans un fichier.Voiçi le code que j'ai actuelleme FileStream et libération de mémoire... [ par GenEars ] GenEars &gt; Bonjour,il y a quelques temps j'ai réutilisé une unité uFileByChunk qui m memorystreams [ par Farfadet07 ] Bonjour,Dans la gestion mémoire de mon programme, je souhaiterais stocker dans un stream toutes les données non nécessaires à un moment donné (notamme free delphi O/R mapping framework [ par terafun ] SalutJe cherchai une framework gratuite pour Object/Relation mapping et je ne trouvai aucune gratuiteSi vous connaissez une, merci de me le dire:) Créer un Active X [ par leroukin ] Bonjour,voici mon problème :Je suis actuellement en train de créer un active X. Tout se passe bien j'arrive à créer mes propriétés et mes procédures, Placer des données d'un TFileStream dans un TMemoryStream [ par christophedlr ] Bonsoir, Je voudrais dans mon programme, lire un fichier don les données que le lis sont transféré vers un TMemoryStream afin de pouvoir les placer e Passer des objets à une DLL [ par christophedlr ] Bonsoir, A la suite du problème que j'avais ici : http://www.delphifr.com/infomsg_PLACER-DONNEES-TFILESTREAM-DANS-TMEMORYSTREAM_1178462.aspx J'ai un


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,733 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.