est-il possible d'utiliser un qfile comme une STD :: iostream? Je suis tout à fait sûr qu'il doit y avoir une enveloppe là-bas. La question est où? P>
J'ai des autres libs, ce qui nécessite un STD :: IStream comme paramètre d'entrée, mais dans mon programme, je n'ai qu'un QFile à ce stade. P>
5 Réponses :
Si vous ne vous souciez pas de beaucoup de performances, vous pouvez toujours tout lire du fichier et le jeter dans un Autre que cela, il ne semble pas que les deux puissent inter-opérer. En tout cas, QT à STL Inter Operations constitue souvent une cause de bugs obscurs et d'incohérences subtiles si la version de STL que QT a été compilée avec est différente de la version de STL que vous utilisez. Cela peut se produire par exemple si vous modifiez la version de Visual Studio. P> std :: stringstream code> puis transmettez-le à votre bibliothèque. (ou la voie à suivre, tamponnant tout à un stringtream, puis écrivez à un qfile) p>
Merci pour votre suggestion, mais Stringstream n'est pas une option car le fichier peut devenir assez grand. Donc, la lecture de toutes les données en mémoire est assez laide.
Si l'objet QFile que vous obtenez n'est pas ouvert pour lire déjà, vous pouvez obtenir le nom de fichier de fichier et ouvrir un objet ifstream. P>
S'il est déjà ouvert, vous pouvez obtenir une poignée de fichier / descripteur avec poignée () code>
et aller de là. Il n'y a pas de moyen portable d'obtenir un FRStream de la poignée de la plate-forme. Vous devrez trouver une solution de contournement pour vos plateformes. P>
Il suffit de recevoir le nom de fichier ne fonctionnera pas pour les ressources QT. La méthode de la poignée () fonctionnera-t-elle si le QFile pointe sur une ressource?
En fait, vous pouvez utiliser Boost.iostreams pour une manière indépendante de la plate-forme de créer un iOSTREAM de FD: vous créez d'abord un tampon de flux: boost :: iostreams :: stream_buffer
std :: iostream (& streambuf) code>.
J'ai proposé ma propre solution en utilisant le code suivant: i fonctionne bien pour lire des fichiers locaux. Je ne l'ai pas testé pour écrire des fichiers. Ce code n'est sûrement pas parfait mais ça marche. P> p>
Je suis venu avec ma propre solution (qui utilise la même idée Stephen Chu suggérées) sortie: p> ce code Utilise STD :: Constructeur de déplacement ifstream (fonctionnalité C ++ x0) spécifiée dans 27.9.1.7 constructeurs de base_ifstream em> section de brouillon de travail, standard pour la programmation Language C ++ strong> : P> voir Comment retourner un FStream (C ++ 0x) pour discussion sur ce sujet. p> p>
basic_ifstream (basic_ifstream && rhs); code>
Effets: Déplacer des constructions de la
rvalue rhs. Ceci est accompli par
Déplacez la construction de la classe de base et
la base de base_filebuf. Prochain
basic_istream :: SET_RDBUF (& SB) est appelé à installer le contenu contenu.
BASIC_FILEBUF. P>
blockQuote>
Pour la ligne ifstream (:: _ fdopen (fichier.handle (fichier.handle (), "r")); > i get:
Erreur: Aucune fonction de correspondance pour appel à 'STD :: BASIC_IFStream
Voici un bon guide pour le sous-classement STD :: Streambuf pour fournir une STD en lecture seule non recherchable :: istream: https: / /stackoverflow.com/a/14086442/316578
Voici une classe simple basée sur cette approche qui adapte un QFile dans un STD :: Streambuf qui peut ensuite être enveloppé dans une STD :: Istream. P>
#include <iostream> #include <QFile> constexpr qint64 ERROR = -1; constexpr qint64 BUFFER_SIZE = 1024; class QFileInputStreamBuffer final : public std::streambuf { private: QFile &m_file; QByteArray m_buffer; public: explicit QFileInputStreamBuffer(QFile &file) : m_file(file), m_buffer(BUFFER_SIZE, Qt::Uninitialized) { } virtual int underflow() override { if (atEndOfBuffer()) { // try to get more data const qint64 bytesReadIntoBuffer = m_file.read(m_buffer.data(), BUFFER_SIZE); if (bytesReadIntoBuffer != ERROR) { setg(m_buffer.data(), m_buffer.data(), m_buffer.data() + bytesReadIntoBuffer); } } if (atEndOfBuffer()) { // no more data available return std::char_traits<char>::eof(); } else { return std::char_traits<char>::to_int_type(*gptr()); } } private: bool atEndOfBuffer() const { return gptr() == egptr(); } };
Que ressemble à une solution, mais cela nécessite de booster.
Pourriez-vous accepter une solution non portable et si oui quelle plate-forme avez-vous besoin de cela pour travailler?
Boost est :: iostream interchangeable avec std :: basic_ostream?