"System.ArgumentException"型的第一次机会例外发生在mscorlib中.dll


  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提出的模式。这样,您将可以访问所需范围内的资源,然后处理。

最新更新