2011-03-27 2 views
2

J'essaie de sauvegarder toutes les données POST sortantes dans QtWebKit.QNetworkAccessManager lit les données sortantes et les conserve dans QIODevice

je le fais à l'aide prioritaire QNetworkReply * QNetworkAccessManager :: createRequest (op opération, const QNetworkRequest & demande, QIODevice outgoingData) méthode et la lecture d'un outgoingData qui contient les données sortantes POST.

Le problème est qu'après l'avoir lu, les données ne sont plus disponibles dans le QIODevice. Comment enregistrer une donnée sortante (PUT, POST) et la garder disponible pour les futures opérations Qt internes?

Si j'ai besoin d'utiliser une autre approche pour enregistrer les données PUT/POST, veuillez me le faire savoir.

Exemple de code:

QNetworkReply *MyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) 
{  
QByteArray bArray = outgoingData->readAll(); 
// save bArray (that contains POST outgoing data) somewhere 
// do other things, and outgoingData now has no data anymore, as it was already read to bArray 
} 

J'ai essayé

QByteArray bArray = outgoingData->readAll(); 
outgoingData->write(bArray); 
qDebug() << bArray; 

Mais dans ce cas j'obtenir "QIODevice :: write: dispositif ReadOnly" message. Comment enregistrer les données sortantes POST/PUT dans Qt?

Merci.

+0

Pouvez-vous ajouter à votre question des informations sur de quoi avez-vous besoin pour ces données? Donnez-nous une image plus large. –

Répondre

2

qint64 QIODevice::peek (char * data, qint64 maxSize)

Reads au plus maxSize octets du dispositif en données, sans effets secondaires (à savoir, si vous appelez read() après coup d'oeil(), vous obtiendrez les mêmes données). Renvoie le nombre d'octets lus. Si une erreur se produit, comme lorsque tentant de jeter un coup d'œil sur un périphérique ouvert en mode WriteOnly, cette fonction renvoie -1.

0 est renvoyé lorsque plus aucune donnée n'est disponible pour la lecture.

EDIT

Oublier pic(), il est pas bon dans cette situation. Vous pouvez l'utiliser, mais vous devrez faire beaucoup de travail pour accomplir ce que vous demandez. Au lieu de cela, lisez Tee is for Tubes, prenez le code à partir de là et utilisez-le.

Lien par courtoisie de peppe de canal #qt irc sur http://irc.freenode.net. Je voudrais remercier peppe et thiago qui ont eu la gentillesse de discuter de ce problème sur le canal #qt avec moi.

Dans le cas où un jour vous voulez voler entrants (par opposition à sortant) des données de QNetworkAccessManager vous trouverez réponse et code How to read data from QNetworkReply being used by QWebPage? question.

+0

Cela ressemble à une bonne solution, je fais outgoingData-> peek (100000); J'ai essayé d'obtenir le maxSize en utilisant outgoingData-> size() mais il retourne toujours 0. Comment obtenir exactement la taille maxSize pour les données? Ou un grand nombre aléatoire est bien? – Zelid

+0

Est-ce que quelqu'un sait pourquoi peak() n'est pas une bonne solution? – izyda

+1

@izyda Je ne suis pas sûr de ce que je voulais dire quand j'ai écrit ceci mais en pensant à cela maintenant les problèmes semblent être a) quand 'peek' comme à tout moment les données pourraient être lues par QtWebKit (dénommé * opérations Qt internes * dans la question) et b) comment garder une trace de ce qui a été jeté ou, en d'autres termes, comment garder la synchronisation entre les données affichées et les données lues et présentes dans le 'QIODevice'. Fondamentalement, pour le faire correctement, vous devrez créer quelque chose de très similaire à la 'Grantlee :: Tee' mentionné dans la modification de ma réponse. –

0

Enregistrez le marqueur de périphérique IO avec QIODevice::pos(). Lire les données de celui-ci. Puis restaurer le marqueur avec QIODevice::seek().

Ceci ne fonctionnera que si le périphérique est un accès aléatoire. Mais je pense que cela couvre la plupart d'entre eux.

+1

le périphérique IO est séquentiel. pos() renvoie toujours 0 – Zelid

1

L'utilisation de pos() et seek() ne fonctionne pas dans ce cas particulier. L'idée d'utiliser peek() semble à la place être bien meilleure. Mais un exemple serait utile. Donc, voici un exemple de la façon d'obtenir un tampon de données à partir des données sortantes de QIODevice dans la fonction createRequest() sans affecter les données d'origine.

if (outgoing != NULL) 
{ 
    const qint64 delta = 100; 

    qint64 length = delta; 
    QByteArray array; 

    while (true) 
    { 
     char *buffer = new char[length]; 
     qint64 count = outgoing->peek(buffer, length); 

     if (count < length) 
     { 
      array = QByteArray(buffer, count); 
      delete buffer; 
      break; 
     } 

     length += delta; 
     delete buffer; 
    } 
} 

Pour une optimisation, vous pouvez ajuster la valeur de 'delta'.

Questions connexes