如何在ASP.Net的内存或磁盘中无缓冲请求地流式传输用户请求中的文件
本文关键字:请求 传输 文件 用户 缓冲 Net 内存 磁盘 ASP | 更新日期: 2023-09-27 18:28:39
这是我将用户输入文件上传到ftp服务器的代码:
public static bool UploadFile(string FilePath, HttpPostedFileBase file)
{
Stream ftpStream = null;
FtpWebRequest request = null;
FtpWebResponse response = null;
try
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(ftpURL + FilePath);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(UserName, Password);
ftpRequest.ContentLength = file.ContentLength;
Stream requestStream = ftpRequest.GetRequestStream();
Byte[] buffer = new Byte[buferSize];
int bytesRead = file.InputStream.Read(buffer, 0, buferSize);
while (bytesRead > 0)
{
requestStream.Write(buffer, 0, bytesRead);
bytesRead = file.InputStream.Read(buffer, 0, buferSize);
}
requestStream.Close();
return true;
}
catch (Exception)
{
return false;
}
}
而且看起来效果不错。但是有一个问题。当用户尝试上传文件时(一个大文件!)它需要很长时间(我认为要将文件保存在主机服务器内存或磁盘中!)再拿一个!在ftp中上传时间长。现在的问题是,我可以通过主机直接将用户输入文件上传到ftp服务器吗。我的意思是使用HttpPostedFile,我有一个来自文件的流来将其保存在Ftp服务器中,并减少上传文件的时间。
(很抱歉语言和信息不好!在MVC中是新的。)
Ty获取答案!。
主要问题是缓冲内存(和磁盘)中的所有请求。
我搜索了一些帮助文章。但我没有声誉把它们联系起来!LOL
我用这种方法解决问题。
这是代码:
[RequestAuthorized(CurrentUser = UserTypes.AdminDeveloper)]
public async Task<ActionResult> Create_Step4()
{
...blabla
var requestStream = HttpContext.Request.GetBufferlessInputStream();
var mpp = new MultipartPartParser(requestStream);
long fileSize = FTPUtility.UploadFile(FilePath, mpp);
}
和
public static long UploadFile(string FilePath, MultipartPartParser file)
{
try
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(ftpURL + FilePath.Substring(1).Replace('''', '/'));
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(UserName, Password);
Stream requestStream = ftpRequest.GetRequestStream();
long fileSize = 0;
Byte[] buffer = new Byte[buferSize];
int bytesRead = file.Read(buffer, 0, buferSize);
fileSize += bytesRead;
while (bytesRead > 0)
{
requestStream.Write(buffer, 0, bytesRead);
bytesRead = file.Read(buffer, 0, buferSize);
fileSize += bytesRead;
}
requestStream.Close();
return fileSize;
}
catch (Exception)
{
return -1;
}
}
您的代码看起来非常好。HttpPostedFileBase只是指向包含文件数据的底层网络流的指针(流)。这个文件永远不会在内存中完全读取,因为您只从底层TCP套接字中分块读取:这也是非常好和高效的。此外,您还直接将读取的字节块复制到远程FTP服务器上的传出套接字。除了提高不同跳之间的网络速度外,优化此代码没有什么可做的。
我只能建议使用Stream.CopyTo
方法对您的代码进行语法简化:
var ftpRequest = (FtpWebRequest)WebRequest.Create(ftpURL + FilePath);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(UserName, Password);
ftpRequest.ContentLength = file.ContentLength;
using (Stream requestStream = ftpRequest.GetRequestStream())
{
file.InputStream.CopyTo(requestStream);
}
return true;
如果到这个FTP服务器的网络连接很慢,并且你无法控制这一点,我可以想到的一个小改进是将上传的文件存储在你的网络服务器上,然后有一些后台作业来运行并上传到远程FTP服务器。这样,客户端就不需要等待文件上传到FTP上——他只需要等待文件被上传到你的网络服务器。