使用ftpWebRequest响应流的StreamReader上的ReadLine抛出ObjectDisposedException [英] ReadLine on StreamReader with ftpWebRequest response stream throws ObjectDisposedException

查看:76
本文介绍了使用ftpWebRequest响应流的StreamReader上的ReadLine抛出ObjectDisposedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好!



我试图逐行从FTP读取文件:

Hello!

I am trying to read file from FTP line by line:

static void Main(string[] args)
{
var uri = new Uri( ....... );
var networkCredential = new NetworkCredential( ......... );
 
var ftpWebRequest = (FtpWebRequest)WebRequest.Create(uri);
ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpWebRequest.KeepAlive = true;
ftpWebRequest.Timeout = System.Threading.Timeout.Infinite;
 
ftpWebRequest.Credentials = networkCredential;
 
FtpWebResponse ftpWebResponse = null;
 
ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse();
 
using (var responseStream = ftpWebResponse.GetResponseStream())
using (var streamReader = new StreamReader(responseStream, Encoding.Default))
{
    var counter = 0;
    while (true)
    {
        if (streamReader.ReadLine() == null) break;
        counter++;
    }
}
}





偶尔ReadLine thorws例外:



Occasionally ReadLine thorws exception:

System.ObjectDisposedException was unhandled
  Message=Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
  Source=System
  ObjectName=System.Net.Sockets.NetworkStream
  StackTrace:
       at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
       at System.Net.FtpDataStream.Read(Byte[] buffer, Int32 offset, Int32 size)
       at System.IO.StreamReader.ReadBuffer()
       at System.IO.StreamReader.ReadLine()
       at Training.Program.Main(String[] args) .....
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 





我不明白我的代码是错的。如何从FTP逐行正确读取文件?



I don't understand that is wrong with my code. How to correctly read file from FTP line by line?

推荐答案

问题在于FtpDataStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)方法。 FtpDataStream在无法读取和处理时关闭。您需要创建自己的自定义FtpDataStream并覆盖Read方法并捕获ObjectDisposedException错误(返回0)以使您离开。未捕获的ObjectDisposedException正在冒泡。





Streamreader有一个名为ReadBuffer的方法,它调用FtpDataStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)方法。由于FtpDataStream关闭并被释放,ReadBuffer永远不会变为零,它需要为Streamreader.readline返回null



声明自定义流类



The problem is with FtpDataStream.Read(Byte[] buffer, Int32 offset, Int32 size) method. FtpDataStream closes when it is unable to read and gets disposed. You need to create your own custom FtpDataStream and override the Read method and catch ObjectDisposedException error (return 0) to get you out.The uncaught ObjectDisposedException is bubbling up.


Streamreader has a method called ReadBuffer which calls the FtpDataStream.Read(Byte[] buffer, Int32 offset, Int32 size) method. Since FtpDataStream closes and gets disposed , ReadBuffer never gets to be zero which it needs to be for Streamreader.readline to return null

Declare a custom stream class

public class custStream : Stream
{
    internal Stream _stream;

    public custStream(Stream stream)
    {
        _stream = stream;
    }
    public override void WriteByte(byte value)
    {
        _stream.WriteByte(value);
    }

    public override int ReadByte()
    {

        try
        {
            return _stream.ReadByte();
        }
        catch (ObjectDisposedException ode)
        {
            return 0; //
        }
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _stream.Seek(offset, origin);
    }

    public override void Flush()
    {
        _stream.Flush();
    }
    public override long Position
    {
        get
        {
            return _stream.Position;
        }
        set
        {
            _stream.Position = value;
        }
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        _stream.Write(buffer, offset, count);
    }

    //this is the one we are really interested in
    public override int Read(byte[] buffer, int offset, int count)
    {
        try
        {
            return _stream.Read(buffer, offset, count);
        }
        catch (ObjectDisposedException ode)
        {
            return 0; //
        }
    }

    public override void SetLength(long value)
    {
        _stream.SetLength(value);
    }



    public override long Length { get { return _stream.Length; } }

    public override bool CanWrite { get { return _stream.CanWrite; } }

    public override bool CanSeek { get { return _stream.CanSeek; } }

    public override bool CanRead { get { return _stream.CanRead; } }

}









在您的代码中将ftpWebResponse.GetResponseStream()改为





In your code change ftpWebResponse.GetResponseStream() to

using (var responseStream = custStream(ftpWebResponse.GetResponseStream()))


到目前为止,我无法解释你所描述的内容,但是......为什么不使用 ftpWebRequest.DownloadData(/ * ... * /),如MSDN帮助页面上的第二个代码示例中所建议的那样: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx [ ^ ]?



By顺便说一下,你没有真正展示工作代码示例。您显示的代码将无法编译:第一个 using 语句的大括号不均衡。你是否完成了 streamReader.ReadLine()的非空结果?



-SA
So far, I could not explain what you describe, but… Why not using ftpWebRequest.DownloadData(/*...*/), as recommended in the second code sample on the MSDN help page: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx[^]?

By the way, you did not really show the working code sample. The code you show won't compile: the curly brackets of first "using" statement are not balanced. Do you through out the non-null result of streamReader.ReadLine()?

—SA


这篇关于使用ftpWebRequest响应流的StreamReader上的ReadLine抛出ObjectDisposedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆