我正在编写一个通用处理程序,该处理程序用于从受保护的FTP服务器下载相当大的文件(超过400 MB)。通过将响应流复制到MemoryStream,然后以二进制方式写入bytes数组,我的代码可以处理小型测试图像。
我的代码如下所示(DownloadFile.ashx):
// Set correct path
string path = ftpHelper.GetCompletePath();
path += "/" + loginId + "/" + folderName + "/" + fileName;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(path);
request.UsePassive = false;
request.Credentials = new NetworkCredential(ftpHelper.Username, ftpHelper.Password);
byte[] fileBytes = null;
using (var response = (FtpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
using (var memoryStream = new MemoryStream())
{
if (responseStream != null) responseStream.CopyTo(memoryStream);
fileBytes = memoryStream.ToArray();
}
}
}
if (fileBytes.Length > 0)
{
context.Response.AppendHeader("Content-Length", fileBytes.Length.ToString());
context.Response.BinaryWrite(fileBytes);
}
request.Abort();
context.ApplicationInstance.CompleteRequest();
问题是:在具有8gb ram的实时网络服务器上(由于它是一个很大的网站,它目前正在使用它的现有ram的60%左右!它可能需要ram升级;-))将CopyTo()和使用带有如此大文件的MemoryStream?
我知道我可以通过ftp:// username:[email protected]将客户端上的下载链接直接设置为FTP服务器,但是FTP上的内容受密码保护是有原因的,因为上面有一些敏感数据。
那么,内存流可以安全地用于如此大的文件吗?如果没有:还有其他方法我忽略了吗?
提前致谢 :-)
MemoryStream
用于大型文件是“安全的”。但是,您会将整个文件加载到内存中,直到Garbage Collection确定是回收该内存的好时机为止,它将一直保留在内存中。
8GB RAM对于“中型”负载生产服务器来说足够了。当然,这是客观的,但是如果单个中流量WebApp使用的内存超过8GB,则应修改一些设计决策。
有两个选项可避免将整个远程文件加载到内存中:
选项2可能类似于:
//...
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);
}
}
//...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句