使用 QNetworkAccessManager 的 post() 方法上传文件

2024-02-17

我在使用 Qt 应用程序时遇到一些问题;特别是 QNetworkAccessManager 类。我正在尝试使用 QNetworkAccessManager 的 post() 方法执行二进制文件的简单 HTTP 上传。文档指出我可以为 post() 提供一个指向 QIODevice 的指针,并且该类将传输在 QIODevice 中找到的数据。这表明我应该能够为 post() 提供一个指向 QFile 的指针。例如:

QFile compressedFile("temp");  
compressedFile.open(QIODevice::ReadOnly);  
netManager.post(QNetworkRequest(QUrl("http://mywebsite.com/upload") ), &compressedFile);  

在我正在开发的 Windows 系统上似乎发生的情况是我的 Qt 应用程序从 QFile 推送数据,但随后没有完成请求;它似乎坐在那里等待文件中显示更多数据。在我手动终止应用程序之前,发布请求不会“关闭”,此时整个文件会显示在我的服务器端。

从一些调试和研究来看,我认为发生这种情况是因为 QFile 的 read() 操作在到达文件末尾时不会返回 -1。我认为 QNetworkAccessManager 正在尝试从 QIODevice 读取数据,直到它从 read() 获得 -1,此时它假设没有更多数据并关闭请求。如果它不断从 read() 中获得零的返回码,则 QNetworkAccessManager 假设可能有更多数据传入,因此它会继续等待该假设数据。

我已经通过一些测试代码确认,在读取到文件末尾后,QFile 的 read() 操作仅返回零。这似乎与 QNetworkAccessManager 的 post() 方法期望 QIODevice 的行为方式不兼容。我的问题是:

  1. QFile 在 Windows 下的工作方式是否存在某种限制?
  2. 我是否应该使用 QFile 或 QNetworkAccessManager 通过 post() 推送文件?
  3. 这根本不起作用吗?我是否必须找到其他方法来上传我的文件?

任何建议或提示将不胜感激。

Update:事实证明,我遇到了两个不同的问题:一个在客户端,一个在服务器端。在客户端,我必须确保我的 QFile 对象在网络事务期间保持不变。 QNetworkAccessManager 的 post() 方法立即返回,但实际上并没有立即完成。您需要将一个槽附加到 QNetworkAccessManager 的 finish() 信号,以确定 POST 何时实际完成。就我而言,很容易将 QFile 或多或少地永久保留,但我还在 finish() 信号上附加了一个槽,以便检查来自服务器的错误响应。

我将信号附加到插槽,如下所示:

connect(&netManager, SIGNAL(finished(QNetworkReply*) ), this, SLOT(postFinished(QNetworkReply*) ) );  

当发送我的文件时,我写了这样的邮政编码(请注意,压缩文件是我的类的成员,因此在此代码之后不会超出范围):

compressedFile.open(QIODevice::ReadOnly);  
netManager.post(QNetworkRequest(QUrl(httpDestination.getCString() ) ), &compressedFile);  

来自 QNetworkAccessManager 的 finish(QNetworkReply*) 信号触发我的 postFinished(QNetworkReply*) 方法。发生这种情况时,我可以安全地关闭compressedFile并删除co​​mpressedFile表示的数据文件。出于调试目的,我还添加了一些 printf() 语句来确认事务已完成:

void CL_QtLogCompressor::postFinished(QNetworkReply* reply)  
{  
    QByteArray response = reply->readAll();  
    printf("response: %s\n", response.data() );  
    printf("reply error %d\n", reply->error() );  
    reply->deleteLater();  
    compressedFile.close();  
    compressedFile.remove();  
}  

由于compressedFile不会立即关闭并且不会超出范围,因此QNetworkAccessManager能够花费尽可能多的时间来传输我的文件。最终交易完成并且我的 postFinished() 方法被调用。

我的另一个问题(这也导致了我所看到的事务从未完成的行为)是我的 Web 服务器的 Python 代码没有正确处理 POST,但这超出了我最初的 Qt 问题的范围。


你正在创造compressedFile放在堆栈上,并将指向它的指针传递给您的 QNetworkRequest (最终是您的 QNetworkAccessManager)。一旦你离开你所在的方法,compressedFile正在超出范围。我很惊讶它没有让你崩溃,尽管行为是未定义的。

您需要创建QFile在堆上:

QFile *compressedFile = new QFile("temp"); 

您当然需要跟踪它,然后delete一旦帖子完成,或者将其设置为QNetworkReply这样当稍后回复被销毁时它就会被销毁:

QFile *compressedFile = new QFile("temp"); 
compressedFile->open(QIODevice::ReadOnly);

QNetworkReply *reply = netManager.post(QNetworkRequest(QUrl("http://mywebsite.com/upload") ), compressedFile); 
compressedFile->setParent(reply);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 QNetworkAccessManager 的 post() 方法上传文件 的相关文章

  • 使用 POST 请求向 Jira API 发送 JSON 时出现 System.Net.WebException

    好吧 伙计们 我已经为这个问题苦苦挣扎了一天左右 但没有明确的解决方案 我将从例外开始 The remote server returned an error NotFound at System Net Browser AsyncHelp
  • Ruby On Rails 与 Windows Vista - 最佳设置? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 您认为 Win Vista 环境中 RoR 的最佳设置是什么 我尝试过 radrails eclipse 插件 它对我来说似乎太庞大了 我也开始
  • Powershell 中的反斜杠

    为什么 split 参数的字符串需要两个反斜杠 而 join 参数的字符串只需要一个反斜杠 反引号是 Powershell 中的转义字符 字符前面的反斜杠有什么作用 path C folder test unit1 testing resu
  • 使用“for”循环迭代目录中的所有文件

    如何使用 a 迭代目录中的每个文件for loop 我如何判断某个条目是目录还是文件 这会递归地列出当前目录及其子目录中的所有文件 并且仅列出文件 for r i in do echo i 此外 如果您在批处理文件中运行该命令 则需要将 符
  • 需要帮助编写循环任务调度程序

    我需要编写一个工具 它将按照用户可配置的时间表运行重复任务 我将用 C 3 5 编写它 它将在 XP Windows 7 或 Windows Server 2008 上运行 完成任务大约需要 20 分钟 用户可能想要设置多种配置 例如每日
  • 如何解析来自基于 C 的 Web 服务器的 HTTP 请求

    我有一个编程项目 我必须创建一个处理 HTTP 请求的多线程 Web 服务器 我刚刚学习了套接字编程 并且运行了一个客户端和一个服务器 我想知道解析 HTTP 请求标头的最佳方法是什么 我看到了这个 如何用C 解析http请求 https
  • java.nio.file.FileSystemException:该进程无法访问该文件,因为该文件正在被另一个进程使用

    我正在编写一个程序 该程序在第一次执行时将自身复制到特定文件夹 在 Linux 或 Windows 中工作 在 Linux 中它工作得很好 但是当我尝试在 Windows 上执行相同操作时 我收到以下错误 java nio file Fil
  • 多个原始输入窗口接收器

    我有一个仅消息窗口 ATL CWindowImpl 它使用 RIDEV INPUTSINK 标志将自身注册为原始输入 这意味着无论该窗口是否是前台窗口 它都会获取所有输入 当该窗口只有一个实例时 这非常有效 但是 当我创建超过 1 个窗口实
  • 如何通过信号和槽传递参数?

    我的 GUI 包括LineEdit and a 按钮 当 的时候按钮单击后 插槽clicked 叫做 我想在之间建立信号槽关系clicked 作为信号和doSomething 作为插槽 问题是doSomething 无权访问 UI 并且do
  • 无法在 Powershell 中运行 R.exe

    我经常发现在命令行 Windows 上运行 R 更有用 然而 当我在 Powershell 中尝试时 我往往会遇到问题 但这可以通过第一次运行轻松克服cmd然后就可以了 这是我执行此操作时遇到的错误R CMD BATCH Invoke Hi
  • 如何从 Java 访问 Windows 设备管理器中的信息?

    我有一个串行 USB 设备 并且其中多个设备可以连接到计算机 我需要查询和检索设备连接到的 COM 端口列表 在 Windows 设备管理器中 您可以获得当前连接的设备的 COM 端口 友好名称 该列表是动态的 从注册表中读取不工作 htt
  • C++/Windows:如何报告内存不足异常(bad_alloc)?

    我目前正在为 Windows MSVC 9 0 应用程序开发基于异常的错误报告系统 即异常结构和类型 继承 调用堆栈 错误报告和日志记录等 我现在的问题是 如何正确报告和记录内存不足错误 当发生此错误时 例如作为bad alloc抛出的ne
  • 如何用 C 语言通过 HTTP 协议发送图像?

    我是一名正在做网络服务器练习的学生 我需要一些帮助 我的网络服务器在文本页面上运行良好 但是每当浏览器发送一个 GET img jpg HTTP 1 1请求 我不知道如何处理 我听说 HTTP 协议是基于文本的 那么如何在 HTTP 响应中
  • 如果 POST 响应仅包含 ID,如何将数据保存到我的 Ember 存储?

    Ember 数据期望我的服务器在每次成功后返回完整的对象POST 但是 我的 API 只返回一种元对象 其中包含id 当 Ember 收到此对象时 记录中的现有数据将被删除 除了id 例如 当我这样做时 var asset App Asse
  • 在 Python 中将 GET 更改为 POST (Flask)

    我正在尝试创建一个简单的应用程序 其中在服务器上生成整数数组并将其发送到客户端 以下是 app py 中的一些示例 工作 代码 from flask import Flask render template request url for
  • CUDA NSight 未随 Windows 8 上的 CUDA 5.0 安装文件一起安装? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 据我所知 Nvidia 网站上没有 Nsight Eclipse 的下载链接 它说它将由 CUDA 5 安装本机安装 但并没有随CUDA安装一起安装
  • 从 Powershell 更新计划任务脚本

    我正在尝试编写一个每天运行一次的 Powershell 脚本 它将执行的众多功能之一是确保脚本本身是最新的 我的问题是 由于我对脚本进行了版本控制 因此我需要更新从脚本中创建的计划任务 我在这里考虑了两种不同的方法 其中我也无法弄清楚 我最
  • 为什么使用 Response 设置后,Request 中的 Cookie 立即可用?

    在页面加载中 如果您立即在下一行中执行 Response Cookies Add 您可以通过 Request Cookies 访问该 cookie 我知道在幕后 cookie 是由 net 添加到 Request Cookies 中的 但原
  • Chrome 问题 - 视频流和会话冲突

    我在使用 javascript 和 PHP 实现视频时遇到问题 索引 php session start do other stuff include video php 视频 php
  • PARITY_NONE 是 C++ Windows 中的关键字吗?

    我正在使用 boost 编写一个串行库 并且我有一个枚举 enum parity t PARITY NONE PARITY ODD PARITY EVEN 我收到如下错误 错误 1 错误 C2059 语法错误 我无法弄清楚问题是什么 然后我

随机推荐