简体   繁体   English

使用 Delphi 将文件上传到 Amazon S3

[英]Upload files to Amazon S3 with Delphi

using code I found in another topic.使用我在另一个主题中找到的代码。 I'm always getting a signature mismatch when authenticating, although accessKeyID and secretAccessKey are verified correct.我在验证时总是遇到签名不匹配,尽管 accessKeyID 和 secretAccessKey 被验证正确。 Also the storage endpoint is correct for the bucket.此外,存储端点对于存储桶也是正确的。 Using Delphi 10 Seattle.使用 Delphi 10 西雅图。 Possible that the CloudComponents have a problem with the region or (local) time ?可能是 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;

I have modified slightly your code to use a TBytesStream instead of a TFileStream to set the file content on a TBytes buffer.我稍微修改了您的代码,以使用 TBytesStream 而不是 TFileStream 来设置 TBytes 缓冲区上的文件内容。 But mostly you have to read the stream, not write it.但大多数情况下,您必须读取流,而不是写入流。

Now it doesn't corrupt its content.现在它不会破坏其内容。

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;

Running your code I have found the problem.运行你的代码我发现了问题。 Just change this line :只需更改此行:

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

By this line :通过这一行:

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

The local path of your file must not be present on the remote call (I guess it confuses the server, thinking that you are trying to reach a resource you have not permissions to).您的文件的本地路径不能出现在远程调用中(我猜它会混淆服务器,认为您正在尝试访问您没有权限的资源)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用临时安全凭证使用Delphi将文件上载到Amazon S3 - Upload files to Amazon S3 with Delphi using temporary security credentials 适用于Delphi 2010的Amazon S3组件 - Amazon S3 components for Delphi 2010 示例应用程序 - Amazon S3 / Indy / Delphi - Sample Application - Amazon S3 / Indy / Delphi Delphi 10.4 亚马逊 aws S3 连接错误 - Delphi 10.4 Amazon aws S3 connection error 为什么我无法从 Delphi VCL 应用程序读取和写入 Amazon S3? - Why am I failing to read and write to Amazon S3 from a Delphi VCL application? 从 Amazon S3 检索 object 后,如何从 stream 获取常规 Delphi 字符串? - How can I get a regular Delphi string from a stream after retrieving an object from Amazon S3? 从我的应用程序(Indy / Delphi)发送文件到ASP页面然后到另一台服务器(Amazon S3) - Sending a file from my application (Indy/Delphi) to an ASP page and then onto another server (Amazon S3) 在C ++ Builder XE5中使用CloudAPI尝试使用MultiPart上传到Amazon S3时遇到错误10054和10053 - Getting error 10054 and 10053 when trying to upload to Amazon S3 using MultiPart uploads, with CloudAPI in C++Builder XE5 如何使用Delphi和OmniThread将文件上传到背景中? - How upload files to azure in background with Delphi and OmniThread? Delphi和IdFtp-如何将所有文件上传到目录 - Delphi and IdFtp - How to upload all files into directory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM