Comment construire une c++ fstream à partir d'une POSIX descripteur de fichier?
Je suis fondamentalement à la recherche pour une version C++ de fonction(). J'ai fait un peu de recherche sur ce sujet et c'est une de ces choses qui semble comme il devrait être plus facile, mais se révèle être très compliqué. Ai-je raté quelque chose dans cette croyance (c'est à dire qu'il est vraiment facile)? Si non, est-il une bonne bibliothèque de là, quelque part gérer cela?
EDIT: Déplacé mon exemple de solution pour une réponse distincte.
- déplacé à une réponse distincte maintenant, merci.
Vous devez vous connecter pour publier un commentaire.
À partir de la réponse donnée par Éric Malenfant:
Basée sur des observations ci-dessus et ma recherche ci-dessous il y a du code qui fonctionne dans les deux variantes, l'une pour libstdc++ et Microsoft Visual C++.
libstdc++
Il y a non-standard
__gnu_cxx::stdio_filebuf
modèle de classe qui hérite destd::basic_streambuf
et a le constructeur suivantavec description Ce constructeur associe un fichier de la mémoire tampon avec un POSIX descripteur de fichier.
Nous créons en passant POSIX poignée (ligne 1) et ensuite on passe à istream du constructeur comme basic_streambuf (ligne 2):
Microsoft Visual C++
Il utilisé pour être non-standard version de ifstream du constructeur prenant POSIX descripteur de fichier, mais il manque à la fois de actuel docs et de code. Il y a un autre non-standard de la version de ifstream du constructeur prenant FICHIER*
et il n'est pas documenté (je ne pouvais même pas trouver tout les vieux de la documentation où il serait présent). Nous appelons (ligne 1) avec le paramètre étant le résultat de l'appel d' _fdopen pour obtenir C FICHIER de flux* de POSIX descripteur de fichier.
std::cout
mise en œuvre est une bonne idée. Je me demandais quelle est la différence entrestdio_filebuf
etstdio_sync_filebuf
?Autant que je sache, il n'y a aucun moyen de le faire en C++ standard. En fonction de votre plate-forme, votre implémentation de la bibliothèque standard peut vous offrir (comme une extension non standard) un fstream constructeur prenant un descripteur de fichier (C'est le cas pour libstdc++, IIRC) ou un
FILE*
comme une entrée.Une autre alternative serait d'utiliser un boost::iostreams::file_descriptor appareil, que vous pouvez l'envelopper dans un boost::iostreams::stream si vous voulez avoir un std::flux d'interface.
Il ya une bonne chance que votre compilateur propose un FICHIER de la base de fstream constructeur, même si c'est non standard. Par exemple:
Mais autant que je sache, il n'y a pas de portable façon de le faire.
Partie de l'original (non spécifiées) la motivation de cette question est d'avoir la possibilité de transmettre des données entre programmes ou entre deux parties d'un programme d'essai en toute sécurité à l'aide d'un fichier temporaire, mais tmpnam() renvoie un message d'avertissement dans gcc, j'ai donc voulu utiliser mkstemp() à la place. Voici un programme de test que j'ai écrit en fonction de la réponse donnée par Éric Malenfant, mais à l'aide de mkstemp() à la place de la fonction(); cela fonctionne sur mon système Ubuntu avec Boost bibliothèques installées:
J'ai essayé la solution proposée ci-dessus pour libstdc++ par Piotr Dobrogost, et a trouvé qu'elle avait une faille douloureuse: en Raison de l'absence d'un bon constructeur de déplacement pour istream, il est très difficile d'obtenir le nouvellement construit istream objet de la création de la fonction. Un autre problème avec lui c'est qu'il fuit un FICHIER objet (même pensé ne pas le sous-jacent posix descripteur de fichier). Voici une autre solution qui permet d'éviter ces problèmes:
L'appel à posix_fadvise() démontre un potentiel d'utilisation. Notez également que l'exemple utilise static_assert et à l'aide de qui sont C++ 11, autre que celui qu'il doit construire l'amende juste en C++ 03 mode.
Il est en fait assez facile. Nicolai M. Josuttis a publié
fdstream
en conjonction avec son livre La Norme C++ de la Bibliothèque - Un Tutoriel et de Référence. Vous pouvez trouver la ligne 184 mise en œuvre ici.Ma compréhension est qu'il n'y a pas d'association avec les pointeurs de FICHIERS ou des descripteurs de fichiers en C++ iostream modèle d'objet afin de garder le code portable.
Cela dit, j'ai vu plusieurs endroits, reportez-vous à la mds-utils ou coup de pouce pour aider à combler cette lacune.