为什么我下载后有时会在文件末尾添加零填充文件?

时间:2012-08-27 05:14:23

标签: delphi delphi-xe indy

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

P.S。我正在使用TFileStream,我将其直接发送到TIdHTTP并使用GET方法下载文件。 其他信息:我处理OnWork事件,该事件将AWorkCount分配给公共int64变量。每次下载文件时,下载的文件大小(那个Int64变量)都会记录到一个文本文件中,而日志中说的是该文件已经完全下载(即使是那些零字节)。

1 个答案:

答案 0 :(得分:1)

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

另请注意,如果TIdHTTP预先知道正在传输多少字节,它会预先分配目标TStream的大小,然后再将数据下载到其中。这是为了在使用TFileStream时加快传输并优化光盘I / O.因此,您应该使用TFileStream来访问与多个同时下载的目标相同的文件,即使它们正在写入文件的不同区域。预先分配多个TFileStream对象可能会相互踩踏,试图将文件大小设置为不同的位置。如果您需要同时下载多个文件,则可以:

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

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