Je recherche essentiellement une version C ++ de fdopen (). J'ai fait un peu de recherche à ce sujet et c'est une de ces choses qui semble devoir être facile, mais qui s'avère très compliquée. Est-ce que je manque quelque chose dans cette croyance (c'est-à-dire que c'est vraiment facile)? Sinon, y a-t-il une bonne bibliothèque quelque part pour gérer cela?
EDIT: J'ai déplacé mon exemple de solution vers une réponse distincte.
c++
posix
fstream
file-descriptor
BD chez Rivenhill
la source
la source
mmap
le fichier et exposé son contenu sous forme de tableau d'octets.Réponses:
D'après la réponse d'Éric Malenfant:
Sur la base des observations ci-dessus et de mes recherches ci-dessous, il existe un code de travail en deux variantes; un pour libstdc ++ et un autre pour Microsoft Visual C ++.
libstdc ++
Il existe un
__gnu_cxx::stdio_filebuf
modèle de classe non standard qui héritestd::basic_streambuf
et a le constructeur suivantavec description Ce constructeur associe un tampon de flux de fichiers à un descripteur de fichier POSIX ouvert.
Nous le créons en passant le handle POSIX (ligne 1) puis nous le passons au constructeur d'istream en tant que basic_streambuf (ligne 2):
Microsoft Visual C ++
Il y avait une version non standard du constructeur d'ifstream prenant le descripteur de fichier POSIX, mais il manque à la fois dans la documentation actuelle et dans le code. Il existe une autre version non standard du constructeur d'ifstream prenant FILE *
et ce n'est pas documenté (je n'ai même pas pu trouver de documentation ancienne où il serait présent). Nous l'appelons (ligne 1) avec le paramètre résultant de l'appel de _fdopen pour obtenir le flux C FILE * à partir du descripteur de fichier POSIX.
la source
std::cout
mise en œuvre est une bonne idée. Je me demande quelle est la différence entrestdio_filebuf
etstdio_sync_filebuf
?AFAIK, il n'y a aucun moyen de le faire en C ++ standard. En fonction de votre plateforme, votre implémentation de la bibliothèque standard peut proposer (en tant qu'extension non standard) un constructeur fstream prenant un descripteur de fichier (c'est le cas pour libstdc ++, IIRC) ou a
FILE*
en entrée.Une autre alternative serait d'utiliser un périphérique boost :: iostreams :: file_descriptor , que vous pouvez envelopper dans un boost :: iostreams :: stream si vous voulez avoir une interface std :: stream.
la source
Il y a de fortes chances que votre compilateur propose un constructeur fstream basé sur FILE, même s'il n'est pas standard. Par exemple:
Mais pour autant que je sache, il n'y a pas de moyen portable de le faire.
la source
Une partie de la motivation originale (non déclarée) de cette question est d'avoir la possibilité de transmettre des données soit entre programmes, soit entre deux parties d'un programme de test en utilisant un fichier temporaire créé en toute sécurité, mais tmpnam () jette un avertissement dans gcc, donc je voulais pour utiliser mkstemp () à la place. Voici un programme de test que j'ai écrit sur la base de la réponse donnée par Éric Malenfant mais en utilisant mkstemp () au lieu de fdopen (); cela fonctionne sur mon système Ubuntu avec les bibliothèques Boost installées:
la source
C'est en fait assez simple. Nicolai M. Josuttis a publié
fdstream
en conjonction avec son livre The C ++ Standard Library - A Tutorial and Reference . Vous pouvez trouver l'implémentation de 184 lignes ici .la source
J'ai essayé la solution proposée ci-dessus pour libstdc ++ par Piotr Dobrogost, et j'ai trouvé qu'elle avait un défaut douloureux: en raison de l'absence d'un constructeur de mouvement approprié pour istream, il est très difficile d'extraire l'objet istream nouvellement construit de la fonction de création . Un autre problème avec celui-ci est qu'il fuit un objet FILE (même si ce n'est pas le descripteur de fichier posix sous-jacent). Voici une solution alternative qui évite ces problèmes:
L'appel à posix_fadvise () démontre une utilisation potentielle. Notez également que l'exemple utilise static_assert et utilise qui sont C ++ 11, à part cela, il devrait très bien se construire en mode C ++ 03.
la source
Je crois comprendre qu'il n'y a aucune association avec des pointeurs FILE ou des descripteurs de fichier dans le modèle d'objet C ++ iostream afin de garder le code portable.
Cela dit, j'ai vu plusieurs endroits faire référence aux mds-utils ou boost pour aider à combler cet écart.
la source