我可以使用Cloud.AmazonAPI监控S3下载的进度吗?

时间:2017-01-27 17:42:52

标签: delphi amazon-web-services amazon-s3

TAmazonStorageService中是否有例程可用于监控下载对象的进度?

我读到可以使用AWS SDK挂钩WriteObjectProgressEvent,但我无法在Embarcadero's AmazonAPI的文档中找到任何相关内容。

1 个答案:

答案 0 :(得分:3)

我不认为这是目前在Delphi中实现的。你可以做的是创建一个流包装器,它将通知写入它的进度。例如,您可以通过ProgressBar

编写以下内容来监控进度
procedure TForm1.OnProgress(const ACount: Int64);
begin
  ProgressBar1.Value := ProgressBar1.Value + ACount;
  Application.ProcessMessages;
end;

procedure TForm1.DownloadFile(const ABucketName: string; const AFileName: TFileName);
var
  ResponseInfo: TCloudResponseInfo;
  StorageService: TAmazonStorageService;
  ObjectName: string;
  FileStream: TStream;
  ProgressStream: TProgressStream;
  MetaData: TStrings;
  Properties: TStrings;
  ContentLength: Int64;
begin
  StorageService := TAmazonStorageService.Create(AmazonConnectionInfo1);
  ResponseInfo := TCloudResponseInfo.Create;
  try
    ObjectName := ExtractFileName(AFileName);
    if StorageService.GetObjectProperties(ABucketName, ObjectName, Properties, MetaData) then
    begin
      try
        ContentLength := StrToInt(Properties.Values['Content-Length']);
      finally
        MetaData.Free;
        Properties.Free;
      end;
      FileStream := TFileStream.Create(AFileName, fmCreate or fmOpenWrite);
      ProgressStream := TProgressStream.Create(FileStream);
      ProgressStream.OnProgress := OnProgress;
      ProgressBar1.Max := ContentLength;
      ProgressBar1.Value := 0;
      try
        StorageService.GetObject(CBucketName, ObjectName, ProgressStream);
      finally
        ProgressStream.Free;
        FileStream.Free;
      end;
    end;
  finally
    StorageService.Free;
    ResponseInfo.Free;
  end;
end;

TProgressStream实现如下

type
  TOnProgressEvent = procedure(const ACount: Int64) of object;
  TProgressStream = class(TStream)
  strict private
    FStream: TStream;
  protected
    function GetSize: Int64; override;
    procedure SetSize(NewSize: Longint); overload; override;
    procedure SetSize(const NewSize: Int64); overload; override;
  public
    OnProgress: TOnProgressEvent;
    function Read(var Buffer; Count: Longint): Longint; overload; override;
    function Write(const Buffer; Count: Longint): Longint; overload; override;
    function Read(Buffer: TBytes; Offset, Count: Longint): Longint; overload; override;
    function Write(const Buffer: TBytes; Offset, Count: Longint): Longint; overload; override;
    function Seek(Offset: Longint; Origin: Word): Longint; overload; override;
    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
    constructor Create(const AStream: TStream);
  end;

constructor TProgressStream.Create(const AStream: TStream);
begin
  FStream := AStream;
end;

function TProgressStream.GetSize: Int64;
begin
  Result := FStream.Size;
end;

procedure TProgressStream.SetSize(NewSize: Longint);
begin
  FStream.Size := NewSize;
end;

procedure TProgressStream.SetSize(const NewSize: Int64);
begin
  FStream.Size := NewSize;
end;

function TProgressStream.Read(var Buffer; Count: Longint): Longint;
begin
  Result := FStream.Read(Buffer, Count);
end;

function TProgressStream.Write(const Buffer; Count: Longint): Longint;
begin
  Result := FStream.Write(Buffer, Count);
end;

function TProgressStream.Read(Buffer: TBytes; Offset, Count: Longint): Longint;
begin
  Result := FStream.Read(Buffer, Offset, Count);
end;

function TProgressStream.Write(const Buffer: TBytes; Offset, Count: Longint): Longint;
begin
  Result := FStream.Write(Buffer, Offset, Count);
  if Assigned(OnProgress) then
  begin
    OnProgress(Count);
  end;
end;

function TProgressStream.Seek(Offset: Longint; Origin: Word): Longint;
begin
  Result := FStream.Seek(Offset, Origin);
end;

function TProgressStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
  Result := FStream.Seek(Offset, Origin);
end;