2009-01-24 7 views
14

Y at-il un moyen de tirer parti des indicateurs de création de fichier dans l'API Win32 tels que FILE_FLAG_DELETE_ON_CLOSE ou FILE_FLAG_WRITE_THROUGH comme décrit ici http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx, mais forcez ce handle dans un std :: ofstream?Puis-je utiliser CreateFile, mais force le handle dans un std :: ofstream?

L'interface avec ofstream est évidemment indépendante de la plate-forme; Je voudrais forcer certains paramètres dépendant de la plate-forme dans «sous le capot» pour ainsi dire.

Répondre

24

Il est possible de joindre un C++ std::ofstream à un descripteur de fichier Windows. Le code suivant fonctionne dans VS2008:

HANDLE file_handle = CreateFile(
    file_name, GENERIC_WRITE, 
    0, NULL, CREATE_ALWAYS, 
    FILE_ATTRIBUTE_NORMAL, NULL); 

if (file_handle != INVALID_HANDLE_VALUE) { 
    int file_descriptor = _open_osfhandle((intptr_t)file_handle, 0); 

    if (file_descriptor != -1) { 
     FILE* file = _fdopen(file_descriptor, "w"); 

     if (file != NULL) { 
      std::ofstream stream(file); 

      stream << "Hello World\n"; 

      // Closes stream, file, file_descriptor, and file_handle. 
      stream.close(); 

      file = NULL; 
      file_descriptor = -1; 
      file_handle = INVALID_HANDLE_VALUE; 
     } 
} 

Cela fonctionne avec FILE_FLAG_DELETE_ON_CLOSE, mais FILE_FLAG_WRITE_THROUGH peut ne pas avoir l'effet désiré, car les données seront mises en mémoire tampon par l'objet std::ofstream, et ne pas être écrit directement sur le disque. Toutes les données dans le tampon seront vidées à l'OS quand stream.close() est appelé, cependant.

+0

Excellent (fonctionne également dans VS2005)! Un scénario que j'ai est pour écrire des informations de comptabilité à un fichier sur un USB avec écriture directe. Parce que ce sera une séquence rapide d'ouverture-écriture-fermeture, l'appel à fermer devrait s'assurer que la mémoire tampon du flux est envoyée vers le système d'exploitation, n'est-ce pas? –

+0

Oui. J'ai mis à jour la réponse pour le mentionner. – ChrisN

+0

Une idée sur la façon de faire la même chose pour 'fstream' au lieu de' ofstream'? – sorin

1

Certains de ces drapeaux sont également disponibles lors de l'utilisation _fsopen/fopen:

FILE* pLockFile = _fsopen(tmpfilename.c_str(), "w", _SH_DENYWR); 
if (pLockFile!=NULL 
{ 
    // Write lock aquired 
    ofstream fs(pLockFile); 
} 

nous ouvrons ici le fichier de sorte lorsque vous faites une chasse d'eau, il écrit à (Et il est supprimé quand il est fermé):

FILE* pCommitFile = fopen(tmpfilename.c_str(), "wcD"); 
if (pCommitFile!=NULL) 
{ 
    // Commits when doing flush 
    ofstream fs(pCommitFile); 
} 
Questions connexes