下载大型csv文件(字符串)分块或流式传输

时间:2018-02-01 09:48:35

标签: c# asp.net-core asp.net-core-mvc

我想通过浏览器下载一个大的csv文件(100+ mb),但是我得到了超时。生成csv文件非常耗时,因此无法在内存中全部读取或首先写入磁盘。

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

FileStreamResult需要在内存中拉出所有流。

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

我尝试编写块来响应,我可以在浏览器中看到文件下载进度但我没有得到文件下载或文件下载对话框。

// 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没有WriteFile(HttpResponseBase)方法可以覆盖FileResult,因为Writing to Output Stream from Action可以写入Response.OutputStream

我该怎么做?

1 个答案:

答案 0 :(得分:0)

您可以通过多种方式进行操作,还有许多有用的课程可供使用。不要打破你的头,因为他们默认是块。

我建议的是StreamContent课程。它需要构造函数的缓冲区大小。

以下是样本的工作原理。

    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;
    }

希望它有所帮助。