使用ftpWebRequest响应流的StreamReader上的ReadLine抛出ObjectDisposedException [英] ReadLine on StreamReader with ftpWebRequest response stream throws ObjectDisposedException
本文介绍了使用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 usingftpWebRequest.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 ofstreamReader.ReadLine()
?
—SA
这篇关于使用ftpWebRequest响应流的StreamReader上的ReadLine抛出ObjectDisposedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文