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"} } };
关键说明
- Base64编码的必要性:API Gateway的
APIGatewayHttpApiV2ProxyResponse通过字符串传递响应体,二进制数据必须用Base64编码才能安全传输,避免字符编码损坏原始数据。设置IsBase64Encoded = true后,API Gateway会自动将Base64字符串解码为原始二进制数据返回给客户端。 - 简化流操作:用
CopyToAsync替代手动循环读取+BinaryWriter的逻辑,代码更简洁高效,还能避免不必要的对象创建。 - 保留响应头:这种方式完全支持自定义响应头,完美解决了你直接返回流无法设置响应头的问题。
你本地写入磁盘正常,是因为直接操作原始二进制流,没有经过字符串编码转换,所以数据没有被破坏。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

