2010-12-03 46 views
0

Comment.Le moyen le plus rapide d'obtenir une partie d'un fichier disque dans une adresse mémoire (pré-allouée) particulière Windows/C++?

Je travaille dans Windows natif. Cela dit, je suis à la recherche d'écrire une fonction dont le prototype est quelque chose comme:

void getData(uint8_t* p, std::string const& fn, size_t off, 
    size_t s, boost::function<void()> const& F); 

J'ai un morceau de mémoire, préalloué sur le tas (avec nouveau). J'ai un fichier sur le disque. Je voudrais spécifier un pointeur dans mon morceau de mémoire ("p"), un nom de fichier ("fn") et un offset dedans ("off"), une taille ("s") et un rappel ("F") . Je voudrais que le sous-programme appelle finalement "F" quand ma mémoire "p" a été remplie avec "s" octets du fichier "fn" au décalage "off". Je vais garantir que "p", "s" et "off" sont alignés sur une puissance prédéfinie de 2, mais je ne voudrais pas que des copies puissent être évitées. Idéalement, il serait DMA les données du disque à mon emplacement directement.

J'ai examiné le mappage de la mémoire du fichier, mais cela nécessiterait de copier les données de la zone mappée dans mon "p". N'y a-t-il pas une façon plus rapide de le faire?

+0

balise 'c' retirée – pmg

+0

J'utiliserais de meilleurs noms de paramètres que p, fn, s et F! – JLWarlow

+0

Hmm ... tout le but des fichiers mappés en mémoire est justement de ne rien copier, mais plutôt de * map *. Peut-être devriez-vous approfondir cette question. C'est une fonctionnalité très puissante de Windows, disponible dès la toute première version de Windows NT. –

Répondre

4

Pourquoi ne pas simplement utiliser le mappage de la mémoire avec MapViewOfFileEx?

Vous pouvez utiliser p comme paramètre lpBaseAddress pour mapper le fichier où vous le souhaitez dans l'espace d'adressage de votre processus.

+1

Exactement. De plus, j'ajouterais que 'boost :: signal' ne correspond pas au" moyen le plus rapide ". En fait, c'est horrible du point de vue de la performance – valdo

+0

Je ne pense pas que ça va marcher. De la documentation: "Aucune autre allocation de mémoire ne peut avoir lieu dans la région utilisée pour le mappage, y compris l'utilisation de la fonction VirtualAlloc ou VirtualAllocEx pour réserver de la mémoire." Je viens de tester cela et MapViewOfFileEx() échoue avec ERROR_INVALID_ADDRESS. Si vous libérez la mémoire, puis essayez de la mapper à nouveau, elle réussira. – Luke

+0

@Luke: En effet. Le pointeur est un indice; rien de plus. Dans mon cas, il est évidemment déjà alloué donc il n'y a aucune chance de le mapper. – gavwould