簡體   English   中英

使用 Delphi 將文件上傳到 Amazon S3

[英]Upload files to Amazon S3 with Delphi

使用我在另一個主題中找到的代碼。 我在驗證時總是遇到簽名不匹配,盡管 accessKeyID 和 secretAccessKey 被驗證正確。 此外,存儲端點對於存儲桶也是正確的。 使用 Delphi 10 西雅圖。 可能是 CloudComponents 的區域或(本地)時間有問題?

Function Amazon_Upload (fileName, bucket, accessKeyID, secretAccessKey : String) : TCallResult;
var
  Service: TAmazonStorageService;
  ConAmazon: TAmazonConnectionInfo;
  info : TCloudResponseInfo;
  upload_stream : TFileStream;
  bytes : TBytes;
begin
  // create file
  upload_stream := TFileStream.Create(fileName,fmOpenRead);
  try
    // filestream to tBytes
    upload_stream.Position := 0;
    SetLength(bytes, upload_stream.Size);
    upload_stream.Write(bytes[0], upload_stream.Size);
    ConAmazon := TAmazonConnectionInfo.Create(nil);
    try
      // amazon connection parameters
      ConAmazon.AccountKey := secretAccessKey;
      ConAmazon.AccountName := accessKeyID;
      ConAmazon.QueueEndpoint := 'queue.amazonaws.com';
      ConAmazon.StorageEndpoint := 's3-eu-central-1.amazonaws.com';
      ConAmazon.TableEndpoint := 'sdb.amazonaws.com';
      ConAmazon.UseDefaultEndpoints := False;
      // storage objects
      info := TCloudResponseInfo.Create;
      Service := TAmazonStorageService.Create(ConAmazon);
      try
        // upload document to storage
        Service.UploadObject(Bucket, fileName, bytes, TRUE, nil, nil, amzbaPrivate, info);
        // get results
        Result.Callstatus := info.StatusCode;
        Result.Success := info.StatusCode in [Ord(rrOK),ord(rrCreated),ord(rrNoContent)];
        Result.Response := TJSONObject.ParseJSONValue(info.StatusMessage);
        If Assigned(OnLog) Then
          FOnlog(info.StatusCode, ConAmazon.StorageEndpoint + #13#10 + bucket + #13#10 + accessKeyID + #13#10 + secretAccessKey, info.StatusMessage, '');
      finally
        info.Free;
        Service.Free;
      end;
    finally
      ConAmazon.Free;
    end;
  finally
    upload_stream.Free;
  end;
end;

我稍微修改了您的代碼,以使用 TBytesStream 而不是 TFileStream 來設置 TBytes 緩沖區上的文件內容。 但大多數情況下,您必須讀取流,而不是寫入流。

現在它不會破壞其內容。

Function Amazon_Upload (fileName, bucket, accessKeyID, secretAccessKey: String) : TCallResult;
var
  Service: TAmazonStorageService;
  ConAmazon: TAmazonConnectionInfo;
  info : TCloudResponseInfo;
  upload_stream : TBytesStream;
  bytes : TBytes;
begin
  // create file
  upload_stream := TBytesStream.Create;
  upload_stream.LoadFromFile(filename);
  try
    // filestream to tBytes
    upload_stream.Position := 0;
    SetLength(bytes, upload_stream.Size);
    upload_stream.ReadBuffer(bytes, upload_stream.Size);
    ConAmazon := TAmazonConnectionInfo.Create(nil);
    try
      // amazon connection parameters
      ConAmazon.AccountKey := secretAccessKey;
      ConAmazon.AccountName := accessKeyID;
      ConAmazon.QueueEndpoint := 'queue.amazonaws.com';
      ConAmazon.StorageEndpoint := 's3-eu-central-1.amazonaws.com';
      ConAmazon.TableEndpoint := 'sdb.amazonaws.com';
      ConAmazon.UseDefaultEndpoints := False;
      // storage objects
      info := TCloudResponseInfo.Create;
      Service := TAmazonStorageService.Create(ConAmazon);
      try
        // upload document to storage
        Service.UploadObject(Bucket, ExtractFileName(fileName), bytes, TRUE, nil, nil, amzbaPrivate, info);
        // get results
        Result.Callstatus := info.StatusCode;
        Result.Success := info.StatusCode in [Ord(rrOK),ord(rrCreated),ord(rrNoContent)];
        Result.Response := TJSONObject.ParseJSONValue(info.StatusMessage);
        If Assigned(OnLog) Then
          FOnlog(info.StatusCode, ConAmazon.StorageEndpoint + #13#10 + bucket + #13#10 + accessKeyID + #13#10 + secretAccessKey, info.StatusMessage, '');
      finally
        info.Free;
        Service.Free;
      end;
    finally
      ConAmazon.Free;
    end;
  finally
    upload_stream.Free;
  end;
end;

運行你的代碼我發現了問題。 只需更改此行:

Service.UploadObject(Bucket, fileName, bytes, TRUE, nil, nil, amzbaPrivate, info);

通過這一行:

Service.UploadObject(Bucket, ExtractFileName(fileName), bytes, TRUE, nil, nil, amzbaPrivate, info);

您的文件的本地路徑不能出現在遠程調用中(我猜它會混淆服務器,認為您正在嘗試訪問您沒有權限的資源)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM