J'essaie d'utiliser QNetworkAccessManager pour télécharger des multipartites HTTP sur un serveur dédié.
Le multipart consiste en une partie JSON décrivant les données étant téléchargées. P>
Les données sont lues à partir d'une série de données en série. , qui crypte les données. p>
Ceci est le code qui crée la demande multipart: p> si le p_encdevice est une instance de qfile, ce fichier obtient Téléchargé juste bien. P> Si le cryptage spécialisé Qiodevice est utilisé (périphérique série), toutes les données sont lues à partir de mon périphérique personnalisé. Toutefois QnetworkAccessManager :: Post () ne fonctionne pas (bloque). P> J'ai lu dans la documentation de qhttppart que: p> Si le périphérique est séquentiel (par exemple, des sockets, mais pas des fichiers),
QnetworkAccessmanager :: Post () devrait être appelé après que le périphérique ait
Terminé émis (). P>
BlockQuote> Malheureusement, je ne sais pas comment cela. P> veuillez indiquer. P> STRY> EDIT: > P> Qiodevice n'a pas de fente fini () du tout. De plus, la lecture de mon iodevice personnalisé ne se produit pas du tout si QNetworkAccessmanager :: Post () n'est pas appelé et que l'appareil ne pourrait pas émettre un tel événement. (Catch 22?) P> Edit 2: strong> P> Il semble que QNAM ne fonctionne pas du tout avec des appareils séquentiels. Voir Discussion sur QT-Project . P> J'ai réussi à "tromper" QNAM pour que cela pense qu'il lisait des périphériques non séquentiels, mais la recherche et la réinitialisation des fonctions empêchent de chercher. Cela fonctionnera jusqu'à ce que qnam essaie de chercher. P>
4 Réponses :
Vous aurez besoin de refactoriser votre code assez tellement que les variables que vous passez à Vous êtes surtout là, il vous suffit de le refroidir et d'ajouter une nouvelle fente que vous pouvez attacher au POST CODE> sont disponibles en dehors de cette fonction que vous avez postées, vous aurez besoin d'une nouvelle fente définie avec le Code pour effectuer le
POST code> à l'intérieur de la mise en œuvre. Enfin, vous devez faire
connect (p_encdevice, signal (fini (fini ()), ceci, emplacement (yourslot ()) code> pour la colle tout ensemble. P>
qiodevice :: fini () code> signal. p>
Nicolas, merci. Cela signifie-t-il effectivement que toutes les données de p_encdevice entrant seront lues dans le tampon interne de QNetworkAccessManager avant que le poste soit appelé? Si tel est le cas, il est beaucoup plus facile si je lisais les données dans qbytearray et que je le transmettes à qhttppartpart :: Setbody.
Il ne sera pas lu dans le tampon de Qnam, essentiellement, vous allez continuer à lire dans le fichier FilePart comme vous le faites maintenant, mais vous aurez besoin de FilePart pour devenir membre de la classe afin que la fente que vous crésiez peut y accéder.
Qiodevice n'a pas du tout terminé. De plus, la lecture de mon iodevice personnalisé ne se produit pas du tout si QNetworkAccessmanager :: Post n'est pas appelé et que l'appareil ne pourrait donc pas émettre un tel événement.
@matejk: En effet, il n'y a pas de Qiodevice :: Terminé (). Je me demande ce que Nicholas voulait écrire à la place ...
J'ai eu plus de succès en créant les données de poste HTTP manuellement qu'avec l'utilisation de qhttppart code> et
qhttpmultiparpart code>. Je sais que ce n'est probablement pas ce que vous voulez entendre, et c'est un peu désordonné, mais cela fonctionne certainement. Dans cet exemple, je lise à partir d'un
qfile code>, mais vous pouvez appeler
readall () code> sur n'importe quel
qiodevice code>. Il convient également de noter,
QioDevice :: Taille () Code> vous aidera à vérifier si toutes les données ont été lues.
<?php
$filename=$_REQUEST['fn'];
$makedir=$_REQUEST['md'];
if($_FILES["attachment"]["type"]=="image/jpeg"){
if(!move_uploaded_file($_FILES["attachment"]["tmp_name"], "/directory/" . $filename)){
echo "File Error";
error_log("Uploaded File Error");
exit();
};
}else{
print("no file");
error_log("No File");
exit();
}
echo "Success.";
?>
Je lis actuellement les données complètes et postez-la, mais je ne peux pas me permettre cela car les fichiers peuvent être très volumineux (quelques Go).
@matejk: Exactement, Readall n'aurait pas besoin de rien de plus que Readall et de poste de Qnam, mais les gens ne peuvent pas le faire lorsqu'il y a de gros fichiers.
Je pense que la capture est que qnetworkAccessmanager ne prend pas en charge codage de transfert chundué lorsque le téléchargement (poste, Mettre) les données. Cela signifie que QNAM doit savoir à l'avance la longueur des données à télécharger, afin d'envoyer l'en-tête de longueur de contenu. Cela implique: p>
() li>; li>;
- ou que les données proviennent d'un périphérique séquentiel, mais le périphérique a déjà tamponné tout (c'est la signification de la note sur
fini () code>) et le signalera (via BytesAvailable () Code>, je suppose); li>
- ou que les données proviennent d'un périphérique séquentiel qui n'a pas tamponné toutes les données, ce qui signifie à son tour signifie
- soit qnam lit et tamponneurs lui-même toutes les données provenant du périphérique (en lisant jusqu'à EOF) li>
- ou l'utilisateur définit manuellement l'en-tête de longueur de contenu pour la demande. LI>
ol> li>
ol>
(sur les deux derniers points, voir les docs pour le QNetworkRequest :: donottbufferuploaddataTtribute.) P>
Ainsi, qhttpmultiparpart partage ces limitations et il est probable qu'il s'agissait d'étouffement sur le cas 3. supposant que vous ne pouvez pas éventuellement tamponner dans la mémoire toutes les données de votre "codeur" Qiodevice, y a-t-il une chance que vous connaissez la taille de la données codées à l'avance et définissez la longueur du contenu sur le QHTTPPART? p>
(comme une dernière note, vous ne devriez pas utiliser QScopedpoinger. Cela supprimera le QNR lorsque le pointeur intelligent tombe hors de portée, mais vous ne voulez pas faire cela. Vous voulez supprimer le QNR quand il émet fini ()). p>
Merci pour des options supplémentaires à essayer. Je définit DonotbufferuploaddaTaAttribute et définir la longueur du contenu explicitement, car je connais la taille à l'avance, mais cela n'a pas vraiment aidé. Le flux d'entrée est lu sur l'EOF, mais tout s'arrête. La documentation mentionne le signal fini (), que QioDevice n'émet pas du tout.
J'utilise intentionnellement Scopedpointer, car le code qui suit est en attente de la fin du QNR.
@MateJK: Oui, j'utilise également QScopedPoinger également dans une fonction principale où QetworkReply ne peut pas être supprimé par elle puisque la boucle d'événement QT défend que. Ouais, il n'y a pas de signal fini (), malheureusement.
d'une discussion séparée dans QT-Project et en inspectant le code source IT Semble que qnam ne fonctionne pas avec séquentiel du tout. La documentation et le code sont fausses. P>
Alors, comment résoudre ce cas d'utilisation? Nous devons faire des compromis avec des données importantes en mémoire, ou vous commencez à modifier à la place?
@LaszlopAppi J'ai créé le périphérique de cryptage de manière à ce qu'il déclare être non séquentiel, mais lire () et rechercher () fonctions de vérification de la position actuelle pour vous assurer que les données sont lues de manière séquentielle. QNAM lit les données séquentiellement. Ce n'est pas bien, mais ça marche.
Je pense que le signal approprié est
QioDevice :: Readchannelfiné () code>. Fondamentalement
QioDevice :: ByteesAvailable () Code> doit renvoyer la valeur correcte pour le fonctionnement.
Avez-vous résolu le problème depuis lors, Matejk?
J'ai réussi à le résoudre, mais pas de manière propre. Voir mon commentaire ci-dessous.