简体   繁体   English

下载大的CSV文件(字符串),分块或流式传输

[英]Download large csv file (string) chunked or streaming

I want to download a large csv file (100+ mb) through browser but I get timeout. 我想通过浏览器下载较大的csv文件(超过100 MB),但超时。 Generating the csv file is time-consuming so I cannot read it all in memory or write to disk first. 生成csv文件非常耗时,因此我无法在内存中全部读取它或先写入磁盘。

public IActionResult Download1()
{
    var bytes = FetchBytes();
    return File(bytes, "text/csv", "download1.csv");
}

FileStreamResult requires pulling all the stream in memory. FileStreamResult需要提取内存中的所有流。

// GET or POST
public IActionResult Download()
{
    var stream = FetchStream();
    return new FileStreamResult(stream, "text/csv");
}

I tried writing chunks to response and I can see the file download progress in browser but I do not get the file download or the file download dialog. 我尝试编写块以响应,但我可以在浏览器中看到文件下载进度,但没有得到文件下载或文件下载对话框。

// GET or POST
public ActionResult Download()
{
    var response = this.Response;
    var size = 4096;
    foreach (var csvBatch in csvBatches)
    {
        byte[] bytes = Encoding.ASCII.GetBytes(csvBatch);
        using (var ms = new MemoryStream(bytes))
        {
            var data = new byte[size];
            var bytesRead = 0;
            do
            {
                bytesRead = ms.Read(data, 0, size);
                response.Body.Write(data, 0, readBytes);
                response.Body.Flush();
            } while (bytesRead > 0);
        }
    }
    response.ContentType = "text/csv";
    response.Headers.Add("Content-Disposition", $"attachment;filename=\"{fileName}\"");
    // this streams the file but does not download or give file download dialog
}

Net Core does not have the WriteFile(HttpResponseBase) method to override for FileResult as per Writing to Output Stream from Action which can write to Response.OutputStream . Net Core没有WriteFile(HttpResponseBase)方法来覆盖FileResult ,而方法是从Action写入可以写入Response.OutputStream Action到Output Stream

How can I do this? 我怎样才能做到这一点?

There are number of ways you can do it and also there are number of helpful classes available to use. 您可以通过多种方式进行操作,也可以使用许多有用的类。 Don't break your head, because they do chunk by default. 不要伤了你的头,因为默认情况下它们会分块。

The one I would recommend is StreamContent class. 我推荐的是StreamContent类。 It takes buffer size on the constructor. 它在构造函数上需要缓冲区大小。

Here is the sample how it works. 这是示例。

    public async Task<HttpResponseMessage> Download()
    {
        var response = new HttpResponseMessage(HttpStatusCode.OK);

        var stream = await GetStreamFromSomewhereMethod();

        var content = new StreamContent(stream, 4096); //buffer is 4KB

        response.Content = content;
        return response;
    }

Hope it helps. 希望能帮助到你。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM