try
{
FtpWebRequest req = (FtpWebRequest)WebRequest.Create("ftp path");
req.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
using (var resp = (FtpWebResponse)req.GetResponse())
{
Console.WriteLine(resp.WelcomeMessage);
}
FtpWebResponse res = (FtpWebResponse)req.GetResponse();
Stream rs = res.GetResponseStream();
StreamReader read1 = new StreamReader(res.GetResponseStream());// prob A
Console.WriteLine(read1.ReadToEnd());
Console.WriteLine("Directory is compleate,status(0)",
res.StatusDescription);
read1.Close();
rs.Close();
}
catch (Exception e1)
{
Console.WriteLine(e1.Message);
}
我正在尝试通过C#访问FTP服务器。
但是,异常的代码错误:
A first chance exception of type "System.ArgumentException" occured in mscorlib.dll. Stream was not readable.
任何帮助将不胜感激。
将所有IDisposable
资源放在using(...) {...}
中。该技术可以预防资源泄漏/关闭资源调用:
try {
FtpWebRequest req = (FtpWebRequest)WebRequest.Create("ftp path");
req.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
// Response: we're going to work wuth respose within "using" block only
using (FtpWebResponse resp = (FtpWebResponse)req.GetResponse()) {
Console.WriteLine(resp.WelcomeMessage);
// Reader: once again reader's opened once and called within using only
using (StreamReader reader = new StreamReader(resp.GetResponseStream())) {
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Directory is complete, status(0)", resp.StatusDescription);
}
}
catch (Exception ex) { // <- Bad idea to catch all possible exceptions without "throw;"
Console.WriteLine(ex.Message);
}
tldr;FtpWebResponse
对象的状态被处置,因此您无法读取响应流。流关闭。
ftpwebresponse的拆卸:
public override void Close()
{
if (Logging.On)
{
Logging.Enter(Logging.Web, this, "Close", "");
}
if (this.HttpProxyMode)
{
this.m_HttpWebResponse.Close();
}
else
{
Stream responseStream = this.m_ResponseStream;
if (responseStream != null)
{
responseStream.Close();
}
}
if (Logging.On)
{
Logging.Exit(Logging.Web, this, "Close", "");
}
}
获得例外的原因是,您正在阅读响应:
using (var resp = (FtpWebResponse)req.GetResponse())
{
Console.WriteLine(resp.WelcomeMessage);
}
,在下一行,您尝试再次将响应读取到另一个变量: res
FtpWebResponse res = (FtpWebResponse)req.GetResponse();
Stream rs = res.GetResponseStream();
StreamReader read1 = new StreamReader(res.GetResponseStream());// prob A
在该节中,您还两次致电res.GetResponseStream()
,但就发生错误而言,这并不重要。即使将其更改为:
FtpWebResponse res = (FtpWebResponse)req.GetResponse();
Stream rs = res.GetResponseStream();
StreamReader read1 = new StreamReader(rs);// prob A
或:
FtpWebResponse res = (FtpWebResponse)req.GetResponse();
StreamReader read1 = new StreamReader(res.GetResponseStream());// prob A
错误发生的原因是被处置的FtpWebResponse
对象的状态;并具有StatusCode = ClosingData
。当我尝试阅读该状态的流时,我会得到您正在遇到的错误。在以前的使用块中,StatusCode = OpeningData
。
但是,如果您只将几行更改为:
using (var resp = (FtpWebResponse)req.GetResponse())
{
Console.WriteLine(resp.WelcomeMessage);
Stream rs = res.GetResponseStream();
StreamReader read1 = new StreamReader(rs);// prob A
Console.WriteLine(read1.ReadToEnd());
Console.WriteLine("Directory is compleate,status(0)", res.StatusDescription);
}
使用范围输入此此功能时,StatusCode = OpeningData
和流可以可读。退出示波器时,StatusCode = ClosingData
和流将不可读取。
希望这有意义,如果我错了,请纠正我。: - )
随着这些小更改,您的代码将按预期运行。但是,您应该研究@dmitrybychenko提出的模式。这样,您将可以访问所需范围内的资源,然后处理。