通过服务器将文件从远程服务器复制到客户端浏览器,而无需将整个文件写入磁盘或内存

本文关键字:文件 服务器 磁盘 内存 浏览器 复制 客户端 | 更新日期: 2023-09-27 18:07:33

是这样的场景。

远程文件服务器上有一个文件(假设我有一个文件托管在DropBox上)

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

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

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

我假设我想使用流对流复制。示例

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

在写入到客户端浏览器之前将整个流复制到内存中。任何想法都很棒。

我需要我的服务器作为代理并屏蔽原始文件位置

谢谢你的帮助

通过服务器将文件从远程服务器复制到客户端浏览器,而无需将整个文件写入磁盘或内存

下面的代码是我最终得到的(缓冲区大小将在生产中改变)它从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();
            }

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

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

考虑使用异步版本的读/写,如果你可以使用c# 4.0的async/awit来使代码可读。

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