5

这就是场景。

远程文件服务器上有一个文件(比如我有一个托管在 DropBox 上的文件)

我想在我的 Web 应用程序(c# asp.net 4.0)上提供该文件作为下载

我想隐藏原始文件的 100% 位置(我希望它看起来来自我的服务器)。

我不想将此文件写入内存或服务器上的磁盘。

我曾假设我想使用流来传输复制。例子

Stream inputStream = response.GetResponseStream();
inputStream.CopyTo(Response.OutputStream, 4096);

inputStream.Flush();

Response.Flush();
Response.End();

但是,这会将整个流复制到内存中,然后再将其写入客户端浏览器。任何想法都会很棒。

我需要我的服务器基本上只是充当代理并屏蔽原始文件位置

谢谢你的帮助。

4

2 回答 2

5

以下代码是我最终得到的(缓冲区大小将在生产中发生变化)这会从 url 获取文件,并开始通过我的服务器将其逐块流式传输到客户端。我花了一点时间才弄清楚的部分是在写入每个块后刷新响应。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(digitalAsset.FullFilePath);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                Response.ClearHeaders();
                Response.ClearContent();
                Response.Clear();
                Response.ContentType = "application/octet-stream";
                Response.AddHeader("Content-Disposition", "attachment;filename=" +     digitalAsset.FileName);

                Stream inputStream = response.GetResponseStream();

                byte[] buffer = new byte[512];
                int read;
                while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    Response.OutputStream.Write(buffer, 0, read);
                    Response.Flush();
                }
                Response.End();
            }

这可以通过我的服务器流式传输任何大小的文件,而无需等待我的服务器将其存储到内存或磁盘中。真正的优势是它使用的内存非常少,因为只存储了缓冲的块。对于客户端,下载立即开始。(这对大多数人来说可能很明显,但对于这个新手来说非常酷)所以我们同时从一个位置下载文件并使用服务器作为一种代理将其上传到另一个位置。

于 2013-04-08T15:02:47.797 回答
1

虽然我看不出为什么CopyTo会在内存中读取整个流(因为任何地方都没有中间流),但您可以手动编写相同的 Copy 以确保它以您想要的方式运行。

考虑使用异步版本的读/写,以及是否可以使用C# 4.0 中的async/awit来使代码可读。

旧方式:异步流处理,新方式异步文件 I/O

于 2013-04-05T20:42:30.877 回答