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

如何从AWS ApiGateway返回流?C# Lambda实现大文件下载

从AWS API Gateway返回流式响应(C# Lambda)

要返回100MB的压缩文件,不能使用普通的APIGatewayHttpApiV2ProxyResponse(会把整个内容加载到内存,易引发溢出),需要启用Lambda响应流式传输,分块返回文件内容。

1. 配置API Gateway

  • 创建或使用现有的HTTP API(REST API也支持流式,但HTTP API配置更简洁)。
  • 在Lambda集成设置中,开启响应流式传输(Response Streaming)选项。

2. 修改Lambda函数代码

将函数返回类型改为IAsyncEnumerable<byte>,分块读取文件流并返回,同时配置正确的响应头。

示例代码:生成压缩文件并流式返回

using System.IO.Compression;
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace YourLambdaNamespace;

public class StreamHandler
{
    public async IAsyncEnumerable<byte> MainHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // 生成压缩文件流(实际场景可替换为从S3/其他存储读取)
        using var zipStream = new MemoryStream();
        using (var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
        {
            var entry = zipArchive.CreateEntry("large-content.txt");
            using var entryWriter = new StreamWriter(entry.Open());
            
            // 模拟写入大内容(根据业务逻辑替换为实际数据)
            for (int i = 0; i < 1500000; i++)
            {
                await entryWriter.WriteLineAsync($"Sample line {i}: 这是压缩文件中的大内容片段");
            }
        }
        zipStream.Position = 0;

        // 分块读取流并返回,避免加载整个文件到内存
        var buffer = new byte[8192]; // 8KB块大小,可按需调整
        int bytesRead;
        while ((bytesRead = await zipStream.ReadAsync(buffer)) > 0)
        {
            var chunk = new byte[bytesRead];
            Array.Copy(buffer, chunk, bytesRead);
            yield return chunk;
        }
    }
}

示例代码:从S3流式读取并返回

如果文件存储在S3,直接流式读取更高效,无需加载到内存:

using Amazon.S3;
using Amazon.S3.Model;
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace YourLambdaNamespace;

public class S3StreamHandler
{
    private readonly IAmazonS3 _s3Client;

    public S3StreamHandler()
    {
        _s3Client = new AmazonS3Client();
    }

    public async IAsyncEnumerable<byte> MainHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // 从S3获取文件流
        var getObjectRequest = new GetObjectRequest
        {
            BucketName = "你的S3存储桶名称",
            Key = "path/to/large-file.zip"
        };

        using var s3Response = await _s3Client.GetObjectAsync(getObjectRequest);
        using var fileStream = s3Response.ResponseStream;

        // 分块返回内容
        var buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = await fileStream.ReadAsync(buffer)) > 0)
        {
            var chunk = new byte[bytesRead];
            Array.Copy(buffer, chunk, bytesRead);
            yield return chunk;
        }
    }
}

3. 关键注意事项

  • 内存与超时设置:Lambda内存至少设置为512MB(处理大文件需要足够内存),超时时间根据文件大小和读取速度调整(比如设置为5分钟)。
  • 响应头配置:可在API Gateway集成中预设Content-Type: application/zip和Content-Disposition: attachment; filename="large-file.zip",确保客户端触发下载。
  • 避免内存溢出:始终分块读取流,不要将整个文件加载到内存中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:35:19