Использование WinInet для определения общего размера файла перед его загрузкой

Я получил приведенный ниже источник со стороннего сайта, объясняющий, как загрузить файл из Интернета с использованием WinInet . Я не слишком хорошо знаком с API, и я взглянул на модуль WinInet , но не увидел каких-либо вызовов API, подобных тому, что мне нужно.

Что я делаю, так это добавляю возможность сообщать о прогрессе загрузки файла. Эту процедуру я уже заключил в TThread , и все работает нормально. Однако только одна недостающая часть: F перед загрузкой укажите общий размер исходного файла.

См. Ниже, где у меня есть комментарий // КАК ПОЛУЧИТЬ ОБЩИЙ РАЗМЕР? Здесь мне нужно узнать, каков общий размер файла, ПРЕЖДЕ чем начать его загрузку. Как мне это сделать? Поскольку этот код, кажется, не знает размера файла, пока он не будет загружен, и это делает это добавление несущественным.

procedure TInetThread.Execute;
const
  BufferSize = 1024;
var
  hSession, hURL: HInternet;
  Buffer: array[1..BufferSize] of Byte;
  BufferLen: DWORD;
  f: File;
  S: Bool;
  D: Integer;
  T: Integer;
  procedure DoWork(const Amt: Integer);
  begin
    if assigned(FOnWork) then
      FOnWork(Self, FSource, FDest, Amt, T);
  end;
begin
  S:= False;
  try
    try
      if not DirectoryExists(ExtractFilePath(FDest)) then begin
        ForceDirectories(ExtractFilePath(FDest));
      end;
      hSession:= InternetOpen(PChar(FAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
      try
        hURL:= InternetOpenURL(hSession, PChar(FSource), nil, 0, 0, 0);
        try
          AssignFile(f, FDest);
          Rewrite(f, 1);
          T:= 0; //HOW TO GET TOTAL SIZE?
          D:= 0;
          DoWork(D);
          repeat
            InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
            BlockWrite(f, Buffer, BufferLen);
            D:= D + BufferLen;
            DoWork(D);
          until BufferLen = 0;
          CloseFile(f);
          S:= True;
        finally
          InternetCloseHandle(hURL);
        end
      finally
        InternetCloseHandle(hSession);
      end;
    except
      on e: exception do begin
        S:= False;
      end;
    end;
  finally
    if assigned(FOnComplete) then
      FOnComplete(Self, FSource, FDest, S);
  end;
end;
9
задан Jerry Dodge 6 February 2012 в 19:22
поделиться