从另一个API下载文件并使用缓冲区返回

时间:2017-12-20 13:36:11

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

我使用PortableWebDavLibrary连接到nextcloud WebDAV API。 https://github.com/DecaTec/Portable-WebDAV-Library

我的简单控制器

// GET api/download/Test/pedro.txt
    [HttpGet("{*name}")]
    public async Task<IActionResult> Get(string name)
    {
        if (String.IsNullOrEmpty(name))
        {
            return BadRequest("TEXT ...");
        }
        try
        {
            var credentials = new NetworkCredential("USER", "PASS");
            using (var webDavSession = new WebDavSession(Global.BASE_URL, credentials))
            {
                var stream = new MemoryStream();
                stream.SetLength(20971520); // TEST set max size

                var responseStream = await webDavSession.DownloadFileAsync(name, stream);

                stream.Seek(0, SeekOrigin.Begin);

                // Response.Headers.Add("content-disposition", "attachment; filename=" + name.TrimEnd('/').Split("/").Last());
                return new FileStreamResult(stream, new MediaTypeHeaderValue("application/octet-stream"))
                {
                    FileDownloadName = name.TrimEnd('/').Split("/").Last()
                };


            }
        }
        catch (Exception e)
        {
            return BadRequest("TEXT ...");
        }

文件已下载,但在将文件保存到内存(MemoryStream)之前,该进程的内存在最大文件中上升到超过2 / 3GB。

当我从另一个API获取文件时,我如何下载?类似于缓冲区

编辑于2017年12月31日

Nextcloud允许下载带有GET请求的文件(没有webdav),这样FileStreamResult可以正常工作。

2 个答案:

答案 0 :(得分:0)

您不太可能按照自己的要求行事,因为cython将成功保留对stream的调用后所需的信息。因此,在发生之前发送任何内容都不准确。

答案 1 :(得分:0)

是的,使用MemoryStream的解决方案不适用于大文件。您可以通过将下载的内容保存到某个临时文件然后上传内容来修复它:

var tempFileName = Path.GetTempFileName();
var stream = new FileStream(tempFileName, FileMode.Create);
await webDavSession.DownloadFileAsync(name, stream);

stream.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(stream, new MediaTypeHeaderValue("application/octet-stream"))
{
    FileDownloadName = name.TrimEnd('/').Split("/").Last()
};

此代码的问题在于它会在服务器上保留临时文件。当临时文件数量达到65535时,GetTempFileName()将最终抛出IOException。要修复此问题,您必须定期删除旧的临时文件,无论是在控制器操作中还是在单独的服务器任务中。