我正在尝试制作一个简单的方法来使用FtpWebRequest
该方法从 FTP 下载文件WebRequestMethods.Ftp.DownloadFile
。问题是我不想显示下载进度,因此需要提前知道文件大小才能计算传输的百分比。但是当我打电话GetResponse
给成员时FtpWebRequest
是ContentLength
-1。
好的-所以我使用该方法提前获取了文件的大小WebRequestMethods.Ftp.GetFileSize
。没问题。然后在获得大小后,我下载文件。
这就是问题出现的地方......
获得大小后,我尝试重用FtpWebRequest
并将方法重置为WebRequestMethods.Ftp.DownloadFile
. 这会导致System.InvalidOperationException
类似“发送请求后无法执行此操作”之类的说法。(可能不是确切的表述——从我得到的瑞典语翻译而来)。
我在其他地方发现,只要我将KeepAlive
属性设置为 true,没关系,连接保持活动状态。这是我不明白的......我创建的唯一对象是我的FtpWebRequest
对象。如果我创建另一个,它怎么知道要使用什么连接?以及什么证件?
伪代码:
Create FtpWebRequest
Set Method property to GetFileSize
Set KeepAlive property to true
Set Credentials property to new NetworkCredential(...)
Get FtpWebResponse from the request
Read and store ContentLength
现在我得到了文件大小。所以是时候下载文件了。设置方法现在会导致上述异常。那我要创建一个新的FtpWebRequest
吗?或者无论如何要重置请求以重用?(关闭响应没有任何区别。)
我不明白如何在不重新创建对象的情况下继续前进。我可以这样做,但感觉不对劲。所以我在这里发帖希望找到正确的方法。
这是(非工作)代码(输入是 sURI、sDiskName、sUser 和 sPwd。):
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(sURI);
request.Method = WebRequestMethods.Ftp.GetFileSize;
request.Credentials = new NetworkCredential(sUser, sPwd);
request.UseBinary = true;
request.UsePassive = true;
request.KeepAlive = true;
FtpWebResponse resp = (FtpWebResponse)request.GetResponse();
int contLen = (int)resp.ContentLength;
resp.Close();
request.Method = WebRequestMethods.Ftp.DownloadFile;
resp = (FtpWebResponse)request.GetResponse();
Stream inStr = resp.GetResponseStream();
byte[] buff = new byte[16384];
sDiskName = Environment.ExpandEnvironmentVariables(sDiskName);
FileStream file = File.Create(sDiskName);
int readBytesCount;
int readTotal=0;
while ((readBytesCount = inStr.Read(buff, 0, buff.Length)) > 0)
{
readTotal += readBytesCount;
toolStripProgressBar1.Value = 100*readTotal/contLen;
Application.DoEvents();
file.Write(buff, 0, readBytesCount);
}
file.Close();
我希望有人可以解释这应该如何工作。提前致谢。