通过 HTTP 上传大文件

2022-08-30 23:16:05

我需要将潜在的大文件(例如,10到100兆字节)文件从桌面应用程序上传到服务器。服务器代码是用 PHP 编写的,PHP 是C++/MFC 中的桌面应用程序。我希望能够在上传中途失败时恢复文件上传,因为该软件将通过不可靠的连接使用。我有哪些选择?我发现了许多用于C++的HTTP上传组件,例如 http://www.chilkatsoft.com/refdoc/vcCkUploadRef.html 看起来很棒,但它似乎没有处理半成品上传的“恢复”(我假设这是因为HTTP 1.1不支持它)。我还查看了 BITS 服务,但对于上载,它需要一个 IIS 服务器。到目前为止,我唯一的选择似乎是将我想上传的文件切成更小的部分(比如每个1兆格),将它们全部上传到服务器,用PHP重新组装它们并运行校验和以查看一切是否顺利。要继续,我需要在上传开始时进行某种形式的“握手”,以找出哪些片段已经在服务器上。我是否必须手动编写代码,或者是否有人知道一个为我完成所有这些工作的库,或者甚至是一个完全不同的解决方案?出于维护原因(防火墙的潜在问题等),我宁愿不切换到另一个支持本机恢复的协议。


答案 1

我迟到了八个月,但我只是偶然发现了这个问题,并惊讶于没有提到webDAV。您可以使用 HTTP PUT 方法进行上传,并包含内容范围标头来处理恢复等。HEAD请求会告诉您文件是否已存在以及它有多大。所以也许像这样:

1) 处理远程文件

2)如果它存在并且大小==本地大小,则上传已完成

3) 如果大小<本地大小,请添加内容范围标头以请求并查找到本地文件中的适当位置。

4)发出PUT请求以上传文件(或部分文件,如果恢复)

5) 如果在 PUT 请求期间连接失败,请从步骤 1 重新开始

您还可以列出 (PROPFIND) 和重命名 (MOVE) 文件,并使用 dav 创建目录 (MKCOL)。

我相信Apache和Lighttpd都有dav扩展。


答案 2

您需要一个标准尺寸(例如 256k)。如果你的文件“abc.txt”,由用户x上传的是78.3MB,它将是313个完整的块和一个较小的块。

  1. 您发送上传请求,说明文件名和大小以及初始线程数。
  2. 你的php代码将创建一个以IP地址和文件名命名的临时文件夹,
  3. 然后,你的应用可以使用多个连接在不同的线程中发送数据,因此你可以同时发送块 1,111,212,313(使用单独的校验和)。
  4. 您的php代码将它们保存到不同的文件,并在验证校验和后确认接收,给出要发送的新块的编号,或使用此线程停止。
  5. 所有线程完成后,您将要求php加入所有文件,如果缺少某些内容,它将转到3

您可以随意增加或减少线程数,因为应用程序正在控制发送。

您可以轻松显示进度指示器,可以是简单的进度条,也可以是接近下层块的详细视图的内容。


推荐