You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda返回S3小型二进制文件时文件大小异常的问题

解决方案:正确处理Lambda返回二进制文件的编码问题

你的猜测完全正确,问题出在**Encoding.Unicode.GetString(ms.ToArray())**这一步:Unicode是双字节编码,把单字节的二进制数据转成Unicode字符串时,每个原始字节会被扩展成两个字节,直接导致文件大小翻倍。

要解决这个问题,同时保留响应头设置,你需要用Base64编码二进制数据,同时告诉API Gateway这是Base64编码的内容,具体修改如下:

修改后的代码

var bucketRequest = new GetObjectRequest
{
    BucketName = uri.Bucket,
    Key = uri.Key,
};
using var bucketResponse = await s3Client.GetObjectAsync(bucketRequest);

await using var responseStream = bucketResponse.ResponseStream;
var ms = new MemoryStream();
// 简化流拷贝逻辑,无需手动循环和BinaryWriter
await responseStream.CopyToAsync(ms, CancellationToken.None);
ms.Position = 0;

return new APIGatewayHttpApiV2ProxyResponse
{
    StatusCode = (int)System.Net.HttpStatusCode.OK,
    // 将二进制数据转换为Base64字符串
    Body = Convert.ToBase64String(ms.ToArray()),
    // 必须设为true,让API Gateway自动解码返回原始二进制数据
    IsBase64Encoded = true,
    Headers = new Dictionary<string, string>
    {
        {"Content-Type", "application/x-bzip2"},
        {"Content-Disposition", "attachment; filename=sites.bz2"}
    }
};

关键说明

  1. Base64编码的必要性:API Gateway的APIGatewayHttpApiV2ProxyResponse通过字符串传递响应体,二进制数据必须用Base64编码才能安全传输,避免字符编码损坏原始数据。设置IsBase64Encoded = true后,API Gateway会自动将Base64字符串解码为原始二进制数据返回给客户端。
  2. 简化流操作:用CopyToAsync替代手动循环读取+BinaryWriter的逻辑,代码更简洁高效,还能避免不必要的对象创建。
  3. 保留响应头:这种方式完全支持自定义响应头,完美解决了你直接返回流无法设置响应头的问题。

你本地写入磁盘正常,是因为直接操作原始二进制流,没有经过字符串编码转换,所以数据没有被破坏。

内容的提问来源于stack exchange,提问作者Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:41:19