델파이 10.2.3의 출시와 함께 더 안정적이고 완성도 높은 버전이 제공되었습니다. 이번 기사에서는 공식 예제를 기반으로 HTTP 비동기 다운로드를 구현하고 다운로드 진행률을 표시하는 방법을 자세히 설명하겠습니다.
핵심 구성 요소는 THttpClient입니다. 먼저 다운로드 작업을 실행하기 위한 THttpClient 객체 FHttpClient를 생성합니다.
procedure TFormDownloadDemo.FormCreate(Sender: TObject);
begin
FHttpClient := THTTPClient.Create;
FHttpClient.OnReceiveData := ReceiveDataEvent;
end;
위 코드에서 FHttpClient에 OnReceiveData 이벤트를 구현하여 다운로드 진행률을 표시합니다. 이 이벤트는 HTTP 다운로드를 비동기로 실행할 때 스레드에서 실행된다는 점을 주의해야 합니다. 구현 코드는 다음과 같습니다:
procedure TFormDownloadDemo.ReceiveDataEvent(const Sender: TObject; AContentLength, AReadCount: Int64;
var Abort: Boolean);
var
LTime: Cardinal;
LSpeed: Integer;
begin
LTime := TThread.GetTickCount - FStartTime; // 소요 시간 계산
LSpeed := (AReadCount * 1000) div LTime; // 다운로드 속도 계산
TThread.Queue(nil,
procedure
begin
ProgressBarDownload.Value := AReadCount; // 다운로드 진행률 표시
LabelSpeed.Text := Format('속도: %d KB/s', [LSpeed div 1024]); // 다운로드 속도 표시
end);
end;
AContentLength: 다운로드 콘텐츠의 총 크기 AReadCount: 현재 다운로드된 바이트 수 이 이벤트에서는 초당 다운로드 바이트 수를 계산하고 ProgressBarDownload 시각적 구성 요소로 진행률을 표시합니다. 이 이벤트가 스레드에서 실행되므로, 인터페이스의 ProgressBarDownload 진행률 동기화를 위해 TThread.Queue를 사용하여 메인 스레드를 동기화합니다.
이제 다운로드 방법을 구현하고 버튼을 통해 이 메서드를 실행하여 다운로드 작업을 수행합니다:
procedure TFormDownloadDemo.StartDownload;
var
DownloadURL: string;
Response: IHTTPResponse;
SaveFileName: string;
FileSize: Int64;
begin
SaveFileName := TPath.Combine(TPath.GetDocumentsPath, EditFileName.Text); // 로컬 저장 파일 경로
try
DownloadURL := EditURL.Text; // 파일 URL 주소
Response := FHttpClient.Head(DownloadURL); // IHTTPResponse 인터페이스 획득
FileSize := Response.ContentLength; // 다운로드 콘텐츠 크기 확인
Memo1.Lines.Add(Format('Head 응답: %d - %s', [Response.StatusCode, Response.StatusText]));
Response := nil;
ProgressBarDownload.Max := FileSize; // 진행률 최대값 설정
ProgressBarDownload.Min := 0;
ProgressBarDownload.Value := 0;
LabelSpeed.Text := '속도: 0 KB/s';
Memo1.Lines.Add(Format('다운로드 중: "%s" (%d 바이트) → "%s"' , [EditFileName.Text, FileSize, SaveFileName]));
// 다운로드 콘텐츠를 저장할 파일 스트림 생성
FFileStream := TFileStream.Create(SaveFileName, fmCreate);
FFileStream.Position := 0;
FStartTime := TThread.GetTickCount; // 다운로드 시작 시간 기록
// 다운로드 시작
FAsyncResult := FHttpClient.BeginGet(DownloadCompleted, DownloadURL, FFileStream);
finally
BStopDownload.Enabled := FAsyncResult <> nil; // 다운로드 중지 활성화
BStartDownload.Enabled := FAsyncResult = nil; // 다운로드 시작 활성화
end;
end;
위 다운로드 방법에 대한 주석이 있지만, 구체적인 다운로드 호출의 목적에 대해 설명이 필요합니다:
FAsyncResult := FHttpClient.BeginGet(DownloadCompleted, DownloadURL, FFileStream);
위 코드에서 FHttpClient.BeginGet를 사용하여 다운로드를 실행하고 세 가지 매개변수를 전달합니다: DownloadCompleted: 다운로드 완료 후 호출될 메서드 DownloadURL: 다운로드할 콘텐츠의 URL FFileStream: 다운로드 콘텐츠를 저장할 파일 스트림
DownloadCompleted 메서드 구현이 중요합니다:
procedure TFormDownloadDemo.DownloadCompleted(const AsyncResult: IAsyncResult);
var
AsyncResponse: IHTTPResponse;
begin
try
AsyncResponse := THTTPClient.EndAsyncHTTP(AsyncResult); // 비동기 응답 인터페이스 획득
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add('다운로드 완료!');
Memo1.Lines.Add(Format('상태: %d - %s', [AsyncResponse.StatusCode, AsyncResponse.StatusText]));
end);
finally
AsyncResponse := nil;
FreeandNil(FFileStream);
BStopDownload.Enabled := False;
BStartDownload.Enabled := True;
end;
end;
이 메서드는 다음과 같이 선언해야 합니다: procedure (const AsyncResult: IAsyncResult);
구현에서는 전달된 매개변수 AsyncResult를 사용하여 다운로드 후 인터페이스 AsyncResponse를 획득하고, 이 인터페이스를 통해 추가 다운로드 정보를 얻습니다. 두 번째로는 다운로드를 저장하는 파일 스트림 FFileStream를 해제하고, 마지막으로 시작 다운로드 버튼과 중지 다운로드 버튼의 상태를 설정합니다. 여기서도 TThread.Synchronize를 사용하여 인터페이스를 동기화하므로 이 메서드 또한 스레드에서 실행됨을 알 수 있습니다.
스레드에서 파일을 다운로드하고 인터페이스에 다운로드 진행률을 표시하는 전체 과정은 기본적으로 설명되었습니다. 구체적인 예제 코드는 다음 위치에서 찾을 수 있습니다: C:\Users\Public\Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\RTL\HttpAsyncDownload
이 예제가 어떤 버전에서 지원되는지 정확히 기억나지는 않지만, 델파이 10.2.3에 포함된 기능이라고 생각됩니다. 중요한 것은 이를 참조하여 자신만의 HTTP 비동기 다운로드를 구현하는 것입니다!
알려진 바와 같이 델파이는 크로스 플랫폼 버전이므로 동일한 구현이 Android, iOS, Windows, OSX, Linux 등에서 모두 사용할 수 있습니다. 이것이 정말 흥미로운 점입니다.