从URL获取图像并上传到Amazon S3

Aki*_*Aki 2 .net vb.net asp.net file-upload amazon-s3

我想直接从URL加载图像,但不将其保存在服务器上,而是想直接将其从内存上传到Amazon S3服务器。

这是我的代码:

Dim wc As New WebClient
Dim fileStream As IO.Stream = wc.OpenRead("http://www.domain.com/image.jpg")

Dim request As New PutObjectRequest()
request.BucketName = "mybucket"
request.Key = "file.jpg"
request.InputStream = fileStream 
client.PutObject(request)
Run Code Online (Sandbox Code Playgroud)

Amazon API给我错误“无法确定内容长度”。流文件流最终以“ System.Net.ConnectStream”结尾,我不确定它是否正确。

完全相同的代码适用于HttpPostedFile中的文件,但现在我需要以这种方式使用它。

有什么想法可以将流转换为Amazon API期望的长度(完整长度)吗?

And*_*nho 6

当我使用GetObjectResponse()方法及其属性ResponseStream将文件从文件夹复制到同一存储桶中的另一个文件夹时,我遇到了相同的问题。我注意到AWS SDK(45年2月3日)有一些故障,如被称为另一种方法WriteResponseStreamToFile()GetObjectResponse,根本不起作用。这些功能的缺乏需要一些解决方法。

我解决了以字节数组打开文件并将其放入MemoryStream对象的问题。

试试这个(C#代码)

WebClient wc = new WebClient();
Stream fileStream =  wc.OpenRead("http://www.domain.com/image.jpg");

byte[] fileBytes = fileStream.ToArrayBytes();

PutObjectRequest request  = new PutObjectRequest();
request.BucketName = "mybucket";
request.Key = "file.jpg";
request.InputStream = new MemoryStream(fileBytes);
client.PutObject(request);
Run Code Online (Sandbox Code Playgroud)

淘汰方法

public static byte[] ToArrayBytes(this Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
Run Code Online (Sandbox Code Playgroud)

您也可以创建不带字节数组的MemoryStream。但是在S3中的第一个PutObject之后,将讨论MemoryStream。如果您需要放置其他对象,建议您选择第一个

 WebClient wc = new WebClient();
 Stream fileStream =  wc.OpenRead("http://www.domain.com/image.jpg");

 MemoryStream fileMemoryStream = fileStream.ToMemoryStream();  

 PutObjectRequest request  = new PutObjectRequest();
 request.BucketName = "mybucket";
 request.Key = "file.jpg";
 request.InputStream = fileMemoryStream ;
 client.PutObject(request);
Run Code Online (Sandbox Code Playgroud)

淘汰方法

    public static MemoryStream ToMemoryStream(this Stream input)
    {
        byte[] buffer = new byte[16 * 1024];

        int read;
        MemoryStream ms = new MemoryStream();
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms;
    }
Run Code Online (Sandbox Code Playgroud)


Sta*_*tas 6

我在类似的情况下遇到了同样的问题。

错误的原因是要上传一个对象,SDK 需要知道将要上传的整个内容长度。为了能够获得流长度,它必须是可搜索的,但从 WebClient 返回的流不是。指示在 PutObjectRequest 中设置 Headers.ContentLength 的预期长度。如果 SDK 无法从流对象确定长度,它将使用此值。

要使您的代码正常工作,请从 WebClient 调用返回的响应标头中获取内容长度。然后设置 PutObjectRequest.Headers.ContentLength。当然这依赖于服务器返回的内容长度值。

Dim wc As New WebClient
Dim fileStream As IO.Stream = wc.OpenRead("http://www.example.com/image.jpg")
Dim contentLength As Long = Long.Parse(client.ResponseHeaders("Content-Length"))

Dim request As New PutObjectRequest()
request.BucketName = "mybucket"
request.Key = "file.jpg"
request.InputStream = fileStream 
request.Headers.ContentLength = contentLength
client.PutObject(request)
Run Code Online (Sandbox Code Playgroud)

  • 这在我从 Zip 存档上传文件时很有帮助。使用 ZipArchiveEntry 因为我能够使用未压缩的长度。 (2认同)