如何使用Delphi 2010优化上传程序?

7

我的Delphi 2010应用程序尚未发布,允许用户将其文件上传到我的服务器。目前我正在使用HTTPS POST发送文件,(简化的)算法基本上是:

  1. 将文件分成“片段”(每个256KB)
  2. 对于每个片段,将其POST到服务器

即对于1MB文件:

--> Get Slice #1 (256KB)
--> Upload Slice #1 using TidHTTP.Post()

--> Get Slice #2 (256KB)
--> Upload Slice #2 using TidHTTP.Post()

--> Get Slice #3 (256KB)
--> Upload Slice #3 using TidHTTP.Post()

--> Get Slice #4 (256KB)
--> Upload Slice #4 using TidHTTP.Post()

我正在使用Indy 10。我一遍又一遍地滥用我的分析器,除了改变上传例程本身之外,几乎没有什么可以优化的了。
我也在使用多线程,尽管我已经尽力优化了代码,但基准测试仍告诉我我可以做得更好(还有其他经过良好优化的软件,几乎比我的上传例程快两倍!)
我知道这不是我的服务器的问题……这里还有我需要探索的想法:
1.我尝试将切片分组为单个POST,自然会导致性能提升(20-35%),但恢复功能现在已经降低了。
2.我也考虑使用SFTP / SSH,但我不确定它是否快速。
3.使用Web套接字实现可恢复上传(如this component),但我对速度也不确定。
现在我的问题是:有没有什么方法可以加速上传?我愿意接受任何建议,包括命令行工具(如果许可证允许我将其与我的应用程序一起发布),前提是:

  1. 支持可恢复上传
  2. 快!
  3. 合理的内存使用
  4. 安全并允许登录/用户身份验证

此外,由于主要安全问题,FTP不是我想要实现的内容。

非常感谢!


1
传输过程中是否使用数据压缩/解压缩技术? - mjn
@mjn:是的(在上传之前,切片已经被压缩,并且我使用Indy的TIdCompressorZLib) - TheDude
@kobik:相当简单的PHP代码(move_uploaded_file() + md5检查 + 简单的SQL插入),我测量了PHP时间,它绝对不是瓶颈。 - TheDude
1个回答

5

我建议使用单个TIdHTTP.Post()方法上传整个文件,而不要进行分块。你可以使用TIdHTTP.OnWork...事件来跟踪已发送到服务器的字节数,以便在需要时知道从哪里恢复。当恢复上传时,您可以使用TIdHTTP.Request.CustomHeaders属性包括一个自定义标头,告诉服务器您从哪里恢复,以便它可以在接受新数据之前将其旧文件回滚到指定的偏移量。


太好了,我不知道我可以恢复POST。让我看看我是否理解正确:在PHP代码中,我添加这个-->header('Accept-Ranges: bytes');而在Delphi中,如果我添加这个(只是一个例子):IdHTTP.Request.CustomHeaders.Add('Range: bytes=5000-'); HTTP POST将自动丢弃额外的字节(回滚)并从第5000个字节开始接收,对吗? - TheDude
或者使用 Content-Range 头部,尽管 RFC 2616 建议它通常只用于响应而不是请求。 - Remy Lebeau
你可以选择编写单独的脚本,一个用于在发送新上传数据时进行POST,另一个用于在恢复以前的上传时进行POST剩余数据。这样,您就不必使用自定义请求头了。您可以发送一个HEAD请求来确定服务器实际上有多少可用字节,然后再开始恢复。 - Remy Lebeau
谢谢Remy,但我有点困惑:为了发送“HEAD”请求,我需要知道文件路径/引用,但如果我没记错的话,PHP脚本只在文件上传完成后才开始执行,或者我漏掉了什么?我的意思是你能详细解释一下吗?谢谢! - TheDude
谢谢Remy,只是为了确保我理解你的意思,假设我有这个Delphi代码和这个旧的PHP代码,你的意思是我需要将PHP代码更改为类似于这样的代码 - TheDude
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接