在delphi中使用AmazonAPI上传文件时获取进度

时间:2017-05-24 06:50:07

标签: delphi amazon-s3

我在单元Data.Cloud.AmazonAPI中使用UploadObject将一些文件上传到AWS S3,它可以工作,但是如何在上传或下载时获取进度信息?这是我的代码:

function TForm1.UploadFile(LocalFilePath: string; RemoteFileName: string; Bucket: string): Boolean;
var
  Service: TAmazonStorageService;
  ConAmazon: TAmazonConnectionInfo;
  FS: TFileStream;
  Content: TBytes;
begin
  try
    ConAmazon := TAmazonConnectionInfo.Create(nil);
    ConAmazon.AccountKey := 'MtJqIM7WyjJA*********************';
    ConAmazon.AccountName := 'AKIAIXVAH*********';
    ConAmazon.QueueEndpoint := 'queue.amazonaws.com';
    ConAmazon.StorageEndpoint := 's3-eu-west-1.amazonaws.com';
    ConAmazon.TableEndpoint := 'sdb.amazonaws.com';
    ConAmazon.UseDefaultEndpoints := True;
    Service := TAmazonStorageService.Create(ConAmazon);
    if FileExists(LocalFilePath) then
    begin
      FS := TFileStream.Create(LocalFilePath, fmOpenRead);
      Content := ByteContent(FS);
      FS.Free;
      Result := Service.UploadObject(Bucket, RemoteFileName, Content, True, nil, nil, amzbaPrivate, nil, OnProgress);
    end
    else
      Result := False;
  finally
    ConAmazon.Free;
    Service.Free;
  end;
end;

1 个答案:

答案 0 :(得分:0)

要下载,请检查此问题Can I monitor the progress of an S3 download using the Cloud.AmazonAPI? 对于上传,它类似,但您需要创建TAmazonStorageService子类,如下所示

type
  TProgressAmazonStorageService = class(TAmazonStorageService)
     function IssuePutRequest(URL: string; Headers: TStringList;
                             QueryParameters: TStringList; const QueryPrefix: string;
                             ResponseInfo: TCloudResponseInfo;
                             Content: TStream; out ResponseString: string): TCloudHTTP; overload; override;
  end;

function TProgressAmazonStorageService.IssuePutRequest(URL: string; Headers: TStringList;
                             QueryParameters: TStringList; const QueryPrefix: string;
                             ResponseInfo: TCloudResponseInfo;
                             Content: TStream; out ResponseString: string): TCloudHTTP;
var
  ProgressStream: TProgressStream;
begin
  Result := PrepareRequest('PUT', Headers, QueryParameters, QueryPrefix, URL);

  try
    ProgressStream := TProgressStream.Create(Content);
    try
      ProgressStream.OnProgress := Form1.OnProgress;
      Form1.ProgressBar1.Max := Content.Size;
      Form1.ProgressBar1.Value := 0;

      if Content <> nil then
        ResponseString := Result.Put(URL, ProgressStream)
      else
        ResponseString := Result.Put(URL);
    finally
      ProgressStream.Free;
    end;

    PopulateResponseInfo(Result, ResponseInfo);
  except
    on E: Exception do
    begin
      Result.Free;
      Raise;
    end;
  end;
end;

进度函数看起来像这样

procedure TForm1.OnProgress(const ACount: Int64);
begin
  Form1.ProgressBar1.Value := Form1.ProgressBar1.Value + ACount;
  Application.ProcessMessages;
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
  if Assigned(OnProgress) then
  begin
    OnProgress(Count);
  end;
  Result := FStream.Read(Buffer, Offset, Count);
end;

function TProgressStream.Write(const Buffer: TBytes; Offset, Count: Longint): Longint;
begin
  Result := FStream.Write(Buffer, Offset, Count);
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;