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

C++ Discussion :

FileMapping : lecture d'un gros fichier


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Points : 96
    Points
    96
    Par défaut FileMapping : lecture d'un gros fichier
    Bonjour,

    J'ai un souci pour lire un fichier de 500+ MB avec le FileMapping.
    Soit le code suivant recopié depuis un exemple trouvé sur le net.

    Le dernier argument de la fonction MapViewOfFile pose un problème - si je laisse
    cette valeur à 0 (ce qui supposément force le mapping à lire tout le fichier), le pointeur
    pFileTemp s'interrompt avant la fin du fichier. Mais si je met l'argument à dwFileSize (forçant le mapping à s'étendre à la taille totale du fichier) ça plante aussi.

    Pour reformuler mon problème, le pointeur pFileTemp pointe bien - pendant un certain temps - sur les caractères du fichier les uns après les autres, mais, à un moment il pointe sur rien ce qui plante le programme.

    Vos avis sont les bienvenus, merci !

    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
     
    HANDLE hFile, hMapFile;
    DWORD dwFileSize;
    char *pFile, *pFileTemp;
     
    hFile = CreateFile(fileName, GENERIC_READ, PAGE_READONLY, NULL, OPEN_EXISTING, 0, NULL); 
     
    dwFileSize = GetFileSize( hFile, NULL );
     
    hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
     
    if( hMapFile == NULL )  {
    	LabelErrMsg->Caption= "CreateFileMapping() fail" ;
    	CloseHandle( hFile );
    	return false;
      }
     
    pFile = (char*)MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, dwFileSize );
     
      std::string token; // chaque mot contenu dans le buffer
      std::vector<std::string> result; // une liste des mots contenu dans le buffer
     
      pFileTemp = pFile;
     
      // Boucle pour tokenizer le string contenu dans le buffer
      for(UINT i = 0; i < dwFileSize; i++ ){ {
     
            // concaténer les caractères lus pour former un mot
    	token = token+(*pFileTemp);
     
            // Si le dernier caractère est une ponctuation, stocker le mot 
    	if(isDelimiter(*pFileTemp)){
    				if(token.size() > 1){
    					token.resize(token.size()-1);
    					pFileTemp--;
    					}
                                    result.push_back(token);
    				token="";
    				}
     
    	pFileTemp++;
     
      }
     
      // fermer, détruire les objets...		
      FlushViewOfFile( pFile, 0 );
      UnmapViewOfFile( pFile );
      CloseHandle( hMapFile );
      CloseHandle( hFile );

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Je crois que tes problèmes sont décrits dans le MSDN ici (http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx) et ici (http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx).

    Je penche pour une limitation sur l'allocation sous-jacente. Lorsque tu mappe une grosse partie de la mémoire, l'OS a besoin de trouver dans sa MMU un ensemble d'adresses virtuelles contigüe - il n'y arrive pas toujours. Mais comme il a réussi à allouer l'ensemble des pages, il n'échoue pas nécessairement. Du coup, tu vas à un certain moment pointer sur de la mémoire qui n'a rien à voir avec le fichier - et générer l'exception EXCEPTION_IN_PAGE_ERROR.

    Dans l'idéal, vu la taille du fichier, il est conseillé de ne travailler que sur une vue réduite. Mapper l'intégralité du fichier en RAM, c'est reposer sur l'espoir que l'OS va faire exactement ce que tu veux en dépit de toutes les contraintes qui le limitent. C'est dangereux, comme tu as pu le voir toi même.

    Tu peux modifier ton algorithme et travailler par fenêtre de 5 ou 10 Mo. Ca n'ira pas nécessairement plus lentement (ce qui va prendre du temps, ce sont les IO disque, mais tu les as de toute manière). MapViewOfFile() permet de spécifier un offset et la taille de la zone que tu souhaite mapper. C'est prévu pour jouer avec des fenêtre de taille raisonnable mappant des petites portions de fichier gigantesques (plusieurs dizaines, plusieurs centaines de Go ; MapViewOfFile() prend un offset de 64 bits).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre régulier
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Points : 96
    Points
    96
    Par défaut
    Merci beaucoup pour les liens.
    Ton explication est la bonne.

    Je vais écrire une boucle pour mapper le fichier par blocs.
    Ceci dit, j'aurais pensé (et préféré que ce soit le cas) que cette boucle était implicite dans le mapping....

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XPATH 1.0] Temps de lecture d'un "gros" fichier XML
    Par Ikki_2504 dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 14/01/2011, 18h27
  2. [XML] Lecture d'assez gros fichiers XML
    Par jeronimo83 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 19/02/2010, 18h26
  3. Optimiser lecture d'un gros fichier
    Par n8ken dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 17/09/2009, 11h14
  4. Lecture d'un gros fichier (jusqu a 300 Mo)
    Par Tidus159 dans le forum Entrée/Sortie
    Réponses: 13
    Dernier message: 10/04/2009, 16h57
  5. Optimisation de la lecture de tres gros fichiers
    Par Lydie dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/07/2004, 14h09

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