3

データを PHP スクリプトに送信し、新しくアップロードされたファイル名を PHP スクリプトからの http 応答として取得する画像アップロード ウィジェットを作成しています。

@jdi、これは 1 つの問題でしたが、qDebug() << rep->readAll() の応答として "? が返されるため、最初の readAll でバッファがクリアされます。

QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
image->save(&buffer, "JPG");

QNetworkAccessManager *http=new QNetworkAccessManager(this);
QNetworkRequest r(QUrl("http://domain/test.php"));

QString bound="---------------------------723690991551375881941828858";
QByteArray data(QString("--"+bound+"\r\n").toAscii());
data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"file\"; filename=\"test.jpg\"\r\n";
data += "Content-Type: image/JPG\r\n\r\n";
data += bytes;
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"desc\"\r\n\r\n";
data += "Description for my image here :)\r\n";
data += "\r\n";
r.setRawHeader(QString("Accept-Encoding").toAscii(), QString("gzip,deflate").toAscii());
r.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
r.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());

rep = http->post(r,data);
connect(http,SIGNAL(finished(QNetworkReply*)),this,SLOT(uploadFinished(QNetworkReply*)));

そしてコールバック関数:

void UploadWidget::uploadFinished(QNetworkReply* r)
{
    r->deleteLater();
    if(r->error() == QNetworkReply::NoError) {
        QByteArray data = r->readAll();
        //QString s = r->readAll(); solved - readAll clears the buffer :)
    }
}

私は QByteArray b = rep->readAll(); で繰り返しました。for (int i = 0 ; i< b.size(); i++) { qDebug() << (char)b.at(i); 一部のシンボルしか取得できないため、bytearray 全体を Qstring に変換する方法はありますか

? 3 , É E , V c D ? ? Ô â C ö f § は「1this is a test1」である必要があります

4

1 に答える 1

2

どうやらあなたのコメントから、あなたの問題は、すべての応答オブジェクトを複数回読んでいたことでした。応答オブジェクトはシーケンシャル IO オブジェクトであるため、一度読み取ると消えてしまいます。

QNetworkReply はシーケンシャル アクセスの QIODevice です。つまり、データがオブジェクトから読み取られると、デバイスによって保持されなくなります。

一度読んで QByteArray を取得します。QString に変換できます。

QByteArray data = r->readAll();
QString dataStr(data);
qDebug() << dataStr;

もう 1 つ注意すべき点は、アップロードの呼び出しごとにまったく新しい QNetworkAccessManager を作成するべきではないということです。あなたは毎回それを漏らしており、アプリケーション全体に1つ保持すると自動的に複数の要求がキューに入れられるという事実をほとんど見逃しています. アプリケーション全体用に 1 つ作成して共有します。

また、メソッドのQHttpMultipartバージョンのpost使用を検討することをお勧めします。これは、すべてのヘッダーを設定するためのよりクリーンな方法と思われるためです。jpeg を投稿するための指定されたメソッドをほとんどコピーできます。

QHttpMultipart JPEG 投稿の例


アップデート

データの読み取りに関する問題の実際の原因は、次のヘッダーです。

r.setRawHeader(QString("Accept-Encoding").toAscii(), 
               QString("gzip,deflate").toAscii());

結果をgzip圧縮して送り返すようにサーバーに指示しています。最終的に読むものは、最初に解凍する必要があります。そのヘッダーを削除するだけで、プレーン テキストのテスト応答を受け取ることができます。

テスト

受信機.h

#include <QObject>

class QNetworkReply;

class Receiver : public QObject
{
    Q_OBJECT
public:
    explicit Receiver(QObject* parent = 0);
public slots:
    void finished(QNetworkReply*);
};

main.cpp

#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>

#include "receiver.h"

Receiver::Receiver(QObject *parent)
    : QObject(parent)
{}

void Receiver::finished(QNetworkReply *reply) {
    reply->deleteLater();
    QByteArray data = reply->readAll();
    qDebug() << data;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QNetworkAccessManager net;
    Receiver rec;

    net.connect(&net, SIGNAL(finished(QNetworkReply*)),
                &rec, SLOT(finished(QNetworkReply*)));

    QNetworkRequest r(QUrl("http://poki.ba/test.html"));
    r.setHeader(r.ContentTypeHeader, QVariant("multipart/form-data;"));
    r.setHeader(r.ContentLengthHeader, QVariant("100"));
//    r.setRawHeader(QString("Accept-Encoding").toAscii(),
//                   QString("gzip,deflate").toAscii());

    net.post(r, QByteArray());

    return a.exec();
}
于 2012-11-26T01:47:21.690 に答える