IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

File Mapping ?


Sujet :

Delphi

  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 26
    Par défaut File Mapping ?
    Bonjour,

    J'ai réalisé une application de Copie de fichier a l'aide de thread et de la methode des flux mais j'ai été un peu déçu de la vitesse, notamment lors de copie de gros fichiers,puis j'ai entendu parler du File Mapping,ici, qui apparemment pourrait certainement m'offrir une methode de copie beaucoup plus rapide puisque l'accès aux fichiers seraient largement plus rapide.

    J'ai vu un exemple d'utilisation avec le tutoriel suivant : Filemapping
    Mais j'aimerai un exemple d'utilisation en delphi, ce que je ne trouve pas... ou alors des explications sur son utilisation etc...

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 988
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 988
    Par défaut
    Sache que SuperCopier est fait en Delphi !
    Les sources sont disponibles !

    Sinon pour le FileMapping, tu n'as que trois fonctions à comprendre
    CreateFile\CreateFileMapping\MapViewOfFile, propose un code (traduire le tutoriel c++ de djmsoftware en Delphi n'est vrai pas difficile !)

    CreateFile = ouvre le fichier et fourni handle fichier
    CreateFileMapping = utilise le handle fichier pour fournir un handle map
    MapViewOfFile = utilise le handle map pour fournir une adresse mémoire

    j'en ai fait un récemment pour partager de la mémoire entre plusieurs processus, c'est assez facile finalement !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 26
    Par défaut
    J'ai tester mais j'ai une erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    FFilehandle:=CreateFile('C:\Users\PHAM\Desktop\test\test.txt',
    GENERIC_READ,
    FILE_SHARE_READ,
    0,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0);
        if (FFilehandle = INVALID_HANDLE_VALUE)   then
       begin
       	MessageBox(NULL,'Impossible d''ouvrir le fichier','Error',NULL);
    end;
     
    FFileMap:=CreateFileMapping(FFileHandle, // handle to file to map
    0, // optional security attributes
    PAGE_READWRITE, // protection for mapping object
    0, // high-order 32 bits of object size
    0, // low-order 32 bits of object size
    0); //
         if (FFileMap= NULL) then
       begin
       	CloseHandle (FFilemap);
       	MessageBox(0,'Impossible de mappe le fichier en mémoire','Error',0);
     
       end;
     
    FMappingPtr:=MapViewOfFile(FFileMap,
     
            FILE_MAP_ALL_ACCESS,
            0,
            0,
            0);
     
            if (FMappingPtr = nil)   then
       begin
       	CloseHandle (FFileMap);
       	CloseHandle (FFileHandle);
       	MessageBox(0,'Impossible de lire le fichier mappé','Error',0);
       end;

    "Impossible de lire le fichier mappé"

    Et je ne sais pas d'ou sa pourrait venir, en fait j'ai adapter une utilisation du filemapping dans un autre language en delphi mais apparament mon Fmappingptr=nil

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 988
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 988
    Par défaut
    La Taille de la mémoire peut-être ?
    Ton fichier test.txt n'est pas vide puisque c'est lui qui détermine la taille de la Map pour CreateFileMapping

    Par contre pour MapViewOfFile, je pense qu'il faut fournir une taille dans dwFileOffsetLow

    Ta gestion des erreurs est étrange !
    Le code devrait être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    FFilehandle := CreateFile('C:\Users\PHAM\Desktop\test\test.txt',
      GENERIC_READ,
      FILE_SHARE_READ,
      0,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      0);
      if (FFilehandle <> INVALID_HANDLE_VALUE) then
      begin
        FFileMap := CreateFileMapping(FFileHandle, // handle to file to map
          0, // optional security attributes
          PAGE_READWRITE, // protection for mapping object
          0, // high-order 32 bits of object size
          0, // low-order 32 bits of object size
          0); //
        if (FFileMap <> NULL) then
        begin
          FMappingPtr := MapViewOfFile(FFileMap,
            FILE_MAP_ALL_ACCESS,
            0,
            0, 
            0); 
          if Assigned(FMappingPtr)   then
          begin
            // Manipulation de FMappingPtr 
          end
          else
          begin
          	CloseHandle (FFileMap);
       	CloseHandle (FFileHandle);
       	MessageBox(0,'Impossible de lire le fichier mappé','Error',0);
          end; 
        end
        else
        begin
          CloseHandle (FFilemap);
          MessageBox(0,'Impossible de mappe le fichier en mémoire','Error',0);
        end;
      end
    else
      MessageBox(NULL,'Impossible d''ouvrir le fichier','Error',NULL);
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 26
    Par défaut
    Oui ma gestion des erreurs était fais juste pour voir ce qui n'aller pas (dans quel type d'erreur j'étais).

    J'ai utilisé ta gestion des erreurs et rajouté un peu de code, ma procédure entière donne sa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    procedure TForm1.Button1Click(Sender: TObject);
    var
    FFilehandle: THANDLE;
    FFileMap: THANDLE;
    FmappingPtr: pchar;
    hFile2:    THANDLE ;
    SizeFile1,BytesWritten: DWORD ;
    begin
     
    FFilehandle := CreateFile('titan.iso',
    GENERIC_WRITE OR GENERIC_READ,
    FILE_SHARE_READ OR FILE_SHARE_WRITE,
      nil,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      0);
      if (FFilehandle <> INVALID_HANDLE_VALUE) then
      begin
        FFileMap := CreateFileMapping(FFileHandle, // handle to file to map
          nil, // optional security attributes
          PAGE_READWRITE, // protection for mapping object
          0, // high-order 32 bits of object size
          2*1024, // low-order 32 bits of object size
          0); //
        if (FFileMap <> NULL) then
        begin
          FMappingPtr := MapViewOfFile(FFileMap,
            FILE_MAP_WRITE,
            0,
            0,
            0);
          if Assigned(FMappingPtr)   then
          begin
            // Manipulation de FMappingPtr
     
       hFile2 := CreateFile('test.iso',GENERIC_WRITE,0,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
       if (hFile2 <> INVALID_HANDLE_VALUE) then
       begin
        SizeFile1 := GetFileSize(FFilehandle,NIL); // recupere taille du fichier 1
     
       WriteFile(hFile2,Fmappingptr,SizeFile1,&BytesWritten,NIL); // Transfert la mémoire mappé dans file 2
     
       // libere les ressources
       end
       else   MessageBox(0,'Impossible de crée le fichier de la copie','Error',0);
     
       UnmapViewOfFile(Fmappingptr);
       CloseHandle(FFileMap);
       CloseHandle(FFilehandle);
       CloseHandle(hFile2);
     
          end
          else
          begin
          	CloseHandle (FFileMap);
       	CloseHandle (FFileHandle);
       	MessageBox(0,'Impossible de lire le fichier mappé','Error',0);
          end;
        end
        else
        begin
          CloseHandle (FFilemap);
          MessageBox(0,'Impossible de mappe le fichier en mémoire','Error',0);
        end;
      end
    else
      MessageBox(NULL,'Impossible d''ouvrir le fichier','Error',NULL);
     
    end;
    Alors mon fichier test2.iso est crée mais fais 0ko, bon c'est sans doute normal j'ai du mal faire mon code mais comme je débute dans ce langage je ne vois probablement pas aussi facilement que certains mes erreurs.

    Comme tu m'as conseillé j'ai mis un dwFileOffsetLow et du coup je sais pas vraiment si c'est grâce à sa mais je n'ai plus d'erreur juste le fais que mon fichier reste a 0ko au lieu de 3Go ^^'.

    NB : je pense que j'ai peut être une erreur dans mes déclaration de variable déjà :s

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 988
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 988
    Par défaut
    Je n'ai jamais utilisé CreateFileMapping\MapViewOfFile pour de l'accès fichier, je ne l'ai utilisé que dans le cadre de mémoire partagé nommée !

    Si ton fichier est à zéro, si tu ne fournis par la taille de CreateFileMapping, cela fait un Map à Zéro !
    Consulte le SDK ou MSDN, c'écrit :

    Citation Envoyé par MSDN
    dwMaximumSizeHigh [in]
    The high-order DWORD of the maximum size of the file mapping object.

    dwMaximumSizeLow [in]
    The low-order DWORD of the maximum size of the file mapping object.

    If this parameter and dwMaximumSizeHigh are 0 (zero), the maximum size of the file mapping object is equal to the current size of the file that hFile identifies.

    An attempt to map a file with a length of 0 (zero) fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of 0 (zero) and reject those files.
    Je ne suis pas convaincu que ton utilisation soit optimale, pourquoi ne pas copier le fichier avec TFileStream et un buffer de 65K ?
    Ou même utilisé un simple CopyFile, tu as des problèmes de performances ? ajoute une patience via CopyFileEx

    Quel est le but véritable, une copie de fichier plus rapide ?
    Etudie le code de "SuperCopier" de ZeuS-[SFX] (très présent sur Phidels)
    Où utilise le directement, l'auteur a bossé énormément sur son projet, à part si tu veux absolument le faire par toi même, tu auras peu de chance de dépasser les perfs de SuperCopier !

    Ce n'est pas un problème de langage, pour le moment, tu te confrontes aux API Windows !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 26
    Par défaut
    Je ne suis pas convaincu que ton utilisation soit optimale, pourquoi ne pas copier le fichier avec TFileStream et un buffer de 65K ?
    Ou même utilisé un simple CopyFile, tu as des problèmes de performances ? ajoute une patience via CopyFileEx
    J'ai déjà fais cette méthode de copie, le TfileStream est rapide mais pas assez meme avec un buffer de 65k (certes sa diminue les accès fichier mais je gagne seulement quelques secondes)
    CopyFile est une méthode standard, loin de répondre a mes attentes.


    J'ai regarder le code de SuperCopier, effectivement le logiciel est sympa et très bien programmer, beaucoup de travail à été fait, mais les methodes sont celles que j'ai déjà tester et je n'en suis pas convaincu car je base mes exemples sur les logiciels de type Teracopy, fastcopy qui sont vraiment très rapide et performant exemple : 180sec pour copier 3Go avec un TFileStream contre 120sec avec FastCopy.

  8. #8
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 26
    Par défaut
    Bon alors j'ai trouver la solution a mon problème. Comme mon systeme fonctionne sous vista 32 bits, je ne pouvais pas prendre des fichiers de plus de 2Go.
    Désormais cela marche parfaitement, le file mapping est très efficace pour la copie de gros fichiers de type 700Mo par exemple ou plus ( bien plus performant que CopyFileEx).
    Mais inefficace pour la copie de petits fichiers.

    Il faut maintenant que je trouve un moyen de "casser" les gros fichiers de plus de 2Go afin qu'il puisse être mappé

    PS: je peux mettre mon code sur demande si cela intéresse quelqu'un

  9. #9
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Février 2006
    Messages
    537
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2006
    Messages : 537
    Par défaut
    Bien sur que ça intéresse...
    Merci à toi

  10. #10
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 26
    Par défaut
    D'accord, voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    procedure TForm1.MapCopy(compteur: integer; laprogressbar: TProgressBar;
      lelabel: TLabel);
    var
    FFilehandle: THANDLE;
    FFileMap: THANDLE;
    FmappingPtr: pchar;
    hFile2:    THANDLE ;
    SizeFile1,BytesWritten: DWORD ;
    begin
     
     
              lelabel.Caption := ObtenirNomfichier(PElementListe(Liste[compteur])
            .sourcefichier);
     
    FFilehandle := CreateFile(pchar(TElementListe(Liste.Items[compteur]^)
          .sourcefichier),
    GENERIC_WRITE OR GENERIC_READ,
    FILE_SHARE_READ OR FILE_SHARE_WRITE,
      nil,
      OPEN_EXISTING,
      FILE_FLAG_NO_BUFFERING,
      0);
      if (FFilehandle <> INVALID_HANDLE_VALUE) then
      begin
        FFileMap := CreateFileMapping(FFileHandle, // handle to file to map
          nil, // optional security attributes
          PAGE_READWRITE, // protection for mapping object
          0, // high-order 32 bits of object size
          0, // low-order 32 bits of object size
          0); //
        if (FFileMap <> NULL) then
        begin
          FMappingPtr := MapViewOfFile(FFileMap,
            FILE_MAP_WRITE,
            0,
            0,
            0);
          if Assigned(FMappingPtr)   then
          begin
            // Manipulation de FMappingPtr
     
       hFile2 := CreateFile(pchar(TElementListe(Liste.Items[compteur]^).destinationfichier +'\'+ TElementListe(Liste.Items[compteur]^).dossier +
        ExtractFileName(TElementListe(Liste.Items[compteur]^).sourcefichier)),GENERIC_WRITE,0,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
       if (hFile2 <> INVALID_HANDLE_VALUE) then
       begin
        SizeFile1 := GetFileSize(FFilehandle,NIL); // recupere taille du fichier 1
     
       WriteFile(hFile2,Fmappingptr[0],SizeFile1,&BytesWritten,NIL); // Transfert la mémoire mappé dans file 2
     
       // libere les ressources
       end
       else   MessageBox(0,'Impossible de lire le fichier mappé','Error',0);
     
       UnmapViewOfFile(Fmappingptr);
       CloseHandle(FFileMap);
       CloseHandle(FFilehandle);
       CloseHandle(hFile2);
     
          end
          else
          begin
          	CloseHandle (FFileMap);
       	CloseHandle (FFileHandle);
       	MessageBox(0,'Impossible de lire le fichier mappé','Error',0);
          end;
        end
        else
        begin
          CloseHandle (FFilemap);
          MessageBox(0,'Impossible de mappe le fichier en mémoire','Error',0);
        end;
      end
    else
      MessageBox(0,'Impossible d''ouvrir le fichier','Error',0);
    end;
    Attention ce code peut surement etre optimiser et mieux gérer, mais il marche très bien ainsi. Il me manque juste a installer la progressbar, mais je vois pas encore comment faire le step it vu que je n'ai pas de buffer :s
    D'ailleurs si quelqu'un a une idée :p

Discussions similaires

  1. [XL-2010] Comment faire du File Mapping en VBA
    Par pikron dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 26/07/2013, 12h51
  2. Réponses: 0
    Dernier message: 10/11/2010, 15h10
  3. Files Mapping pour stocker des structures de données
    Par Targan dans le forum Débuter
    Réponses: 0
    Dernier message: 27/12/2007, 11h38
  4. File Mapping c'est quoi?
    Par deck_bsd dans le forum Windows
    Réponses: 2
    Dernier message: 15/10/2006, 13h06
  5. hibernate & eclipse(Hibernate Mapping File)
    Par coquero dans le forum Hibernate
    Réponses: 5
    Dernier message: 06/07/2006, 11h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo