C# 使用memorystream下载大文件
我正在编写一个通用处理程序,用于从安全的FTP服务器下载相当大(400+mb)的文件。通过将响应流复制到MemoryStream,然后对字节数组进行二进制写入,我让代码在小测试图像上运行 我的代码如下(DownloadFile.ashx): 问题是:在一个有8gb内存的实时Web服务器上(由于它是一个相当大的网站,目前使用的内存约为现有内存的60%!它可能需要ram升级;-),制作CopyTo()并使用MemoryStream处理如此大的文件是否安全 我知道我可以通过直接将客户端上的下载链接设置为FTP服务器,但是FTP上的内容是有密码保护的,因为上面有一些敏感数据 那么,memorystream与如此大的文件一起使用安全吗?如果没有,还有没有其他我忽略的方法C# 使用memorystream下载大文件,c#,ftp,C#,Ftp,我正在编写一个通用处理程序,用于从安全的FTP服务器下载相当大(400+mb)的文件。通过将响应流复制到MemoryStream,然后对字节数组进行二进制写入,我让代码在小测试图像上运行 我的代码如下(DownloadFile.ashx): 问题是:在一个有8gb内存的实时Web服务器上(由于它是一个相当大的网站,目前使用的内存约为现有内存的60%!它可能需要ram升级;-),制作CopyTo()并使用MemoryStream处理如此大的文件是否安全 我知道我可以通过直接将客户端上的下载链接设置
提前感谢:-)使用内存流应该可以。记住,您不需要一次写入整个文件,继续写入数据,直到返回所有数据,然后关闭响应
看一看这个问题,了解如何将天分块返回
MemoryStream
用于大型文件是“安全的”。但是,您将把整个文件加载到内存中,它将一直保留在内存中,直到垃圾收集确定是回收该内存的好时机
8GB的RAM对于“中等”负载的生产服务器来说已经足够了。当然,这是客观的,但是如果一个中低流量的WebApp使用的内存超过8GB,那么一些设计决策应该修改
有两个选项可以避免将整个远程文件加载到内存中:
//...
using (Stream responseStream = response.GetResponseStream())
{
Response.BufferOutput= false; // to prevent buffering
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytesRead);
}
}
//...
非常感谢你的快速响应,伊恩:-我也找到了这个:(页面中间的C示例),所以基本上我可以通过这样做来跳过内存流。我要试一试@bomortensen是的,通常是任何流,只需一次写入位,谢谢您的答案和代码示例!我复制了你的代码,它可以开箱即用——而且速度非常快!:-)使用我的CopyTo()memorystream逻辑,实际开始下载图像需要一秒钟左右的时间。我没想到它会“正常工作”,这是一个不错的奖励!我也会研究改变缓冲区的大小。您可以调整它以匹配ftp服务器的吞吐量;这可能会对操作的整体速度产生另一个影响。当我使用这个文件时,我用firefox以二进制模式打开了这个文件!如何确保开始下载?
//...
using (Stream responseStream = response.GetResponseStream())
{
Response.BufferOutput= false; // to prevent buffering
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytesRead);
}
}
//...
void WriteFile(string path, string filename)
{
using (FileStream fs = File.OpenRead(path))
{
//response is HttpListenerContext.Response...
Response.ContentType = System.Net.Mime.MediaTypeNames.Application.Octet;
Response.AddHeader("Content-disposition", "attachment; filename=" + filename);
byte[] buffer = new byte[64 * 1024];
int read;
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, read);
Response.OutputStream.Flush(); //seems to have no effect
}
Response.OutputStream.Close();
}
File.Delete(path);
Response.End();
}