1.输入参数

1)上传文件路径IMAGE_PATH 2)上传后在阿里云的图像命名OBJECT_NAME

2.实现功能

1)将文件路径指向的图片上传到阿里云

3.注意事项

1)需要提前配置好阿里云存储对象OSS

2)访问ID,密匙等内容一定不要填错

3)注意边缘设备时间准确

4.关键代码

 

void Keytest::uploadImageToCloud(const QString& IMAGE_PATH,const QString& OBJECT_NAME)
{
    const QString ACCESS_KEY_ID = "LTAI5t5p3HeDqqr9A25awihj";//访问密钥 ID
    const QString ACCESS_KEY_SECRET = "057W97oFISSzyzBGvpM6sqFeTymqA";//访问密钥
    const QString BUCKET_NAME = "mydata-ssy";//存储桶名称
    const QString ENDPOINT = "oss-cn-beijing.aliyuncs.com";//服务访问地址
//上面四项内容一定不要填错
    // 1. 读取图片文件内容
    QFile file(IMAGE_PATH);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "无法打开文件:" << file.errorString();
        return ;
    }
    QByteArray fileData = file.readAll();
//    file.close();

    // 2. 自动检测图片MIME类型
    QMimeDatabase mimeDb;
    QMimeType mimeType = mimeDb.mimeTypeForFile(IMAGE_PATH);
    QString contentType = mimeType.name();
    if (contentType.isEmpty()) {
        contentType = "application/octet-stream";
    }
    // 3. 计算图片内容的MD5
    QByteArray md5Data = QCryptographicHash::hash(fileData, QCryptographicHash::Md5).toBase64();
    QString contentMd5 =QString(md5Data); //md5Data.toBase64();

    // 4. 生成时间戳 (RFC 1123格式)
    QString dateValue = QDateTime::currentDateTimeUtc().toString("ddd, dd MMM yyyy hh:mm:ss") + " GMT";

    // 5. 构造待签名字符串
    QString resource = "/" + BUCKET_NAME + "/" + OBJECT_NAME;
    QString stringToSign = "PUT\n" +contentMd5 + "\n" +contentType.toUtf8() + "\n" +dateValue.toUtf8() + "\n" +resource.toUtf8();

    // 6. 计算签名
    QByteArray key = ACCESS_KEY_SECRET.toUtf8();
    QByteArray data = stringToSign.toUtf8();
    QMessageAuthenticationCode hmac(QCryptographicHash::Sha1);
    hmac.setKey(key);
    hmac.addData(data);
    QByteArray signature = hmac.result().toBase64();
    // 7. 构造URL
    QUrl url("https://" + BUCKET_NAME + "." + ENDPOINT + "/" + OBJECT_NAME);

    // 8. 创建网络请求
    QNetworkRequest request(url);


    request.setRawHeader("Authorization", "OSS " + ACCESS_KEY_ID.toUtf8() + ":" + signature);
    request.setRawHeader("Date", dateValue.toUtf8());
    request.setRawHeader("Content-Type", contentType.toUtf8());
    request.setRawHeader("Content-Md5", contentMd5.toUtf8());
    //
    request.setRawHeader("Content-Length", QString::number(file.size()).toUtf8());
    // 9. 发送请求
    QNetworkAccessManager manager;
    //
    QNetworkReply *reply = manager.put(request, &file);
    QEventLoop loop;
    QTimer  timer;
    timer.setSingleShot(true);
//    QString fileUrl;
    printf("344555\n\n\n");
    qDebug() << "===== 完整请求信息 =====";
    qDebug() << "AccessKey ID:" << ACCESS_KEY_ID;
    qDebug() << "Bucket:" << BUCKET_NAME;
    qDebug() << "Endpoint:" << ENDPOINT;
    qDebug() << "Object:" << OBJECT_NAME;
    qDebug() << "Local file:" << IMAGE_PATH;
    qDebug() << "File size:" << fileData.size() << "bytes";
    qDebug() << "Content-MD5:" << contentMd5;
    qDebug() << "Content-Type:" << contentType;
    qDebug() << "Date:" << dateValue;
    qDebug() << "String to sign:" << stringToSign;
    qDebug() << "Signature:" << signature;
    qDebug() << "Full URL:" << url.toString();
    qDebug() << "===========================\n";
    QObject::connect(reply, &QNetworkReply::finished, &loop,&QEventLoop::quit);
       // 10. 处理响应
    QObject::connect(&timer, &QTimer::timeout, &{
           if (reply->isRunning()) reply->abort();
           loop.quit();
       });
       timer.start(30000); // 30秒超时
       loop.exec();
       if (reply->error() == QNetworkReply::NoError) {
           qDebug() << "上传成功! URL: https://" << BUCKET_NAME << "." << ENDPOINT << "/" << OBJECT_NAME;
       } else {
           qDebug() << "cuowudaima:" << reply->error();
           qDebug() << "上传失败:" << reply->errorString();
           qDebug() << "HTTP状态码:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

           // 网络诊断建议
           // 输出服务器返回的XML错误信息
                   QByteArray errorData = reply->readAll();
                   if (!errorData.isEmpty()) {
                       qDebug() << "服务器返回:";
                       qDebug() << errorData;

                       // 尝试解析OSS错误XML
                       QXmlStreamReader xml(errorData);
                       while (!xml.atEnd()) {
                           xml.readNext();
                           if (xml.isStartElement()) {
                               if (xml.name() == "Code") {
                                   qDebug() << "错误代码:" << xml.readElementText();
                               } else if (xml.name() == "Message") {
                                   qDebug() << "错误消息:" << xml.readElementText();
                               } else if (xml.name() == "RequestId") {
                                   qDebug() << "请求ID:" << xml.readElementText();
                               }
                           }
                       }
                   }

                   qDebug() << "===== 签名验证信息 =====";
                   qDebug() << "String to sign:" << stringToSign;
                   qDebug() << "Calculated signature:" << signature;
                   qDebug() << "=========================";
               }
       reply->deleteLater();
       file.close(); // 现在可以安全关闭文件
   }

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐