0

我正在使用Indy和开发下载管理器Delphi XE(应用程序使用Multithreading尝试与服务器建立多个连接)。一切正常,但有时最终下载的文件已损坏,当我检查下载的临时文件时,我发现其中 2 或 3 个在其末尾填充了零。(每个临时文件是每个连接的下载结果)。文件越大,我得到的临时文件越多。例如,在其中一个 65,536,000 字节的临时文件中,只有 0-34,359,426 的范围是有效的,而从 34,359,427 到 64,535,999 它全是零。如果我删除这些零,应用程序将自动下载丢失的段,我得到的结果是健康的下载文件,如果问题不再发生的话。我想摆脱临时文件末尾的那些零,而不会降低下载速度。

PS我正在使用TFileStream,我将它直接发送到并使用方法TIdHTTP下载文件。GET附加信息:我处理OnWork分配AWorkCount给公共int64变量的事件。每次下载文件时,下载的文件大小(该Int64变量)都会记录到一个文本文件中,并且从日志中可以看出该文件已完全下载(即使是那些零字节)。

4

1 回答 1

1

在请求下载范围之前,请确保服务器确实支持下载字节范围。如果服务器不支持范围,则服务器将忽略请求的范围,而是发送整个文件。如果您还没有这样做,您应该TIdHTTP.Head()在调用之前使用 to 文本获取范围支持TIdHTTP.Get()。无论如何,您还需要执行此操作以检测远程文件自上次下载后是否已更改。任何体面的下载管理器都需要能够处理这样的事情。

还要记住,如果TIdHTTP事先知道要传输多少字节,它将在将TStream数据下载到其中之前预先分配目标的大小。这是为了在使用TFileStream. 因此,即使它们正在写入文件的不同区域,您也不应该用于访问与多个同时下载的目标相同的文件TFileStream预先分配多个TFileStream对象可能会相互践踏,试图将文件大小设置为不同的位置。如果您需要同时下载多个文件,则可以:

1) 将每个部分下载到一个单独的文件中,并在获得所需的所有部分后根据需要将它们复制到最终文件中。

2) 使用自定义TStream类,或 Indy 的TIdEventStream类,自己管理文件 I/O,这样您就可以忽略TIdHTTP的预分配尝试,并确保多个文件 I/O 操作不会错误地相互重叠。

于 2012-08-27T23:44:26.037 回答