You have to check the size of the remote file, and the size of the local file (if exists).
If the size of the remote file is larger than the size of the local file, then you have to set the Ranges
property of the Request
property of TIdHTTP
to the starting point (the local file size).
For example, if the remote file size is 100000 bytes, and the local file size is 80000 bytes, then you have to set http.Request.Ranges
to start at 80000.
Here is a fully working code for you to use:
function FileSize(const FileName: string): Int64;
var
AttributeData: TWin32FileAttributeData;
begin
if GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @AttributeData) then
begin
Int64Rec(Result).Lo := AttributeData.nFileSizeLow;
Int64Rec(Result).Hi := AttributeData.nFileSizeHigh;
end
else
Result := -1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
http: TIdHTTP;
FS: TFileStream;
file_url: String;
file_path: String;
web_file_size: Integer;
local_file_size: Integer;
IhaveToDownload: Boolean;
begin
file_url := 'http://212.183.159.230/50MB.zip';
file_path := 'C:\50MB.zip';
IhaveToDownload := False;
FS := nil;
http := TIdHTTP.Create(nil);
try
//I will check if local file exists
if FileExists(file_path) then
begin
//I have to run http.Head() to get the ContentLength of the remote file.
http.Head(file_url);
//web_file_size now has the remote file size in bytes
web_file_size := http.Response.ContentLength;
//local_file_size now has the local file size in bytes
local_file_size := FileSize(file_path);
//check if remote file is bigger than local file (so I have to resume download)
if (web_file_size > local_file_size) and (http.Response.AcceptRanges = 'bytes') then
begin
//remote file is bigger than local file, so I will resume download.
http.Request.Ranges.Add.StartPos := local_file_size;
FS := TFileStream.Create(file_path, fmOpenReadWrite);
FS.Position := local_file_size;
IhaveToDownload := True;
end
else if web_file_size <> local_file_size then
begin
//remote file is not equal with local file, so I will restart download.
FS := TFileStream.Create(file_path, fmCreate);
IhaveToDownload := True;
end;
end
else
begin
//File does not exist locally. I will create a new local file
FS := TFileStream.Create(file_path, fmCreate);
IhaveToDownload := True;
end;
if IhaveToDownload then
http.Get(file_url, FS);
finally
FS.Free;
http.Free;
end;
end;