【问题标题】:How to optimize upload routine using Delphi 2010?如何使用 Delphi 2010 优化上传程序?
【发布时间】:2012-03-17 14:50:02
【问题描述】:

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

  1. 将文件拆分为“切片”(每个 256KB)
  2. 对于每个切片,将其发布到服务器

即。对于 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。我(ab)一遍又一遍地使用我的分析器,除了更改上传例程本身之外,没有什么可以优化的了。

我也在使用多线程,即使我尽了最大努力优化我的代码,我的基准测试仍然告诉我我可以做得更好(还有其他优化良好的软件确实可以实现很多更好的时机...几乎是我上传程序的两倍!)

我知道这不是我的服务器的错...以下是我仍然需要探索的想法:

  1. 我尝试在单个 POST 中对切片进行分组,这自然会提高性能 (20-35%),但现在恢复能力有所降低。

  2. 我也想过使用SFTP / SSH,但我不确定它是否很快。

  3. 使用web sockets实现可恢复上传(如this component),我也不确定速度。

现在我的问题是:有什么办法可以加快上传速度吗?我愿意接受任何我可以实施的建议,包括命令行工具(如果许可证允许我将其与我的应用程序一起发布),前提是:

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

另外,由于主要的安全问题,我不想实现 FTP。

非常感谢!

【问题讨论】:

  • 传输是否使用数据压缩/解压?
  • @mjn:是的(切片在上传之前已经压缩 + 我使用 Indy 的 TIdCompressorZLib)
  • @kobik:相当简单的php代码(move_uploaded_file() + md5检查+简单的sql插入),我测量了php的时间,绝对不是瓶颈。

标签: performance delphi upload indy resume-upload


【解决方案1】:

我建议为整个文件创建一个TIdHTTP.Post(),而完全不分块。您可以使用TIdHTTP.OnWork... 事件来跟踪发送到服务器的字节数,以便在需要时知道从哪里恢复。恢复时,您可以使用TIdHTTP.Request.CustomHeaders 属性包含一个自定义标头,告诉服务器您要从哪里恢复,因此它可以在接受新数据之前将其先前的文件回滚到指定的偏移量。

【讨论】:

  • 太好了,我不知道我可以恢复 POST。让我看看我是否做对了:在 PHP 代码中,我添加了这个 --> header('Accept-Ranges: bytes');如果我添加这个(只是一个例子)在Delphi中: IdHTTP.Request.CustomHeaders.Add('Range: bytes=5000-'); HTTP POST 将自动丢弃额外的字节(回滚)并从第 5000 个字节开始拾取,对吗?
  • 要恢复之前的POST,您可以传入一个TStream,其中仅包含剩余数据。但是服务器必须支持恢复并将新数据附加到现有文件中,而不是重新覆盖文件。上传恢复不是标准 HTTP 协议的一部分。 Accept-Ranges 响应标头和Range 请求标头仅用于下载,不适用于上传。当我提到自定义标头时,我指的是您自己设计的自定义 X-... 标头,您的 PHP 代码可以查找,例如:X-Resuming-From: ...
  • Content-Range 标头,尽管 RFC 2616 建议它通常仅用于响应,而不是请求。
  • 您也可以编写单独的脚本,一个到POST 发送数据以进行新的上传,另一个发送到POST 剩余数据到恢复之前的上传。然后您不必使用自定义请求标头。您可以发送HEAD 请求以确定服务器在开始恢复之前实际可用的字节数。
  • 谢谢 Remy,但我很困惑:为了发送“HEAD”请求,我需要知道文件路径/引用,但如果我没记错的话,PHP 脚本只会启动它的执行文件上传完成之后,还是我在这里遗漏了什么?我的意思是你能详细说明一下吗?谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多