16

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

4

9 回答 9

21

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

1) HEAD 远程文件

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

3) 如果 size < local size,则添加 Content-Range 标头以请求并查找本地文件中的适当位置。

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

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

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

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

于 2009-09-30T18:18:58.253 回答
2

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

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

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

您可以轻松地显示进度指示器,可以是简单的进度条,也可以是类似于 downthemall 的块详细视图的东西。

于 2009-01-29T23:37:40.207 回答
2

libcurl (C api) 可能是一个可行的选择

-C/--continue-at 继续/恢复给定偏移量的先前文件传输。给定的偏移量是将被跳过的确切字节数,从源文件的开头开始计数,然后再传输到目标。如果与上传一起使用,则 curl 不会使用 FTP 服务器命令 SIZE。使用“-C -”告诉 curl 自动找出在哪里/如何恢复传输。然后它使用给定的输出/输入文件来解决这个问题。如果多次使用此选项,将使用最后一个

于 2009-10-09T09:31:44.057 回答
2

谷歌创建了一个可恢复的 HTTP 上传协议。请参阅https://developers.google.com/gdata/docs/resumable_upload

于 2012-08-04T14:28:02.277 回答
1

逆转整个过程是一种选择吗?我的意思是,不要将文件推送到服务器,而是让服务器使用标准 HTTP GET 和所有花里胡哨(如接受范围等)拉文件。

于 2009-01-29T16:20:47.047 回答
1

也许最简单的方法是创建一个上传页面,该页面将接受参数中的文件名和范围,例如http://yourpage/.../upload.php?file=myfile&from=123456并在客户端处理简历(也许您可以添加一个函数来检查服务器已收到哪些范围)

于 2009-01-29T18:32:38.590 回答
1

@ Anton Gogolev Lol,我只是在想同样的事情——把整个事情颠倒过来,让服务器成为客户端,而客户端成为服务器。感谢 Roel,为什么它不起作用,我现在更清楚了。

@Roel 我建议实现 Java 上传器 [JumpLoader 很好,它的 JScript 接口甚至是 PHP 服务器端示例代码]。当涉及到 BIIIGGG 文件时,Flash 上传者遭受了严重的损失 :) ,以千兆字节为单位。

于 2010-11-12T22:31:10.063 回答
0

F*EX 可以通过 HTTP 上传高达 TB 范围的文件,并且能够在链接失败后恢复。它不能完全满足您的需要,因为它是用 Perl 编写的,并且需要基于 UNIX 的服务器,但客户端可以在任何操作系统上。也许它对你有帮助:http: //fex.rus.uni-stuttgart.de/

于 2013-07-17T23:14:41.113 回答
0

存在称为TUS的协议,用于可恢复上传,并在PHPC++中实现了一些实现

于 2021-01-28T13:39:32.133 回答