如何防止意外处置 Streams? (StreamReader, FileStream...)
How do I prevent an unexpected disposal of Streams? (StreamReader, FileStream...)
我有一些代码,我试图在从主机下载大型机文件之前读取其中的一行。我创建了一个 Stream class 的实例作为一个名为 reader
的对象,从主机检索 FTP 数据流并将其放入 Stream 对象,然后创建原始副本Stream 对象及其数据到另一个名为 readerCopy
的 Stream 对象中。我认为,我的问题是,当我将 readerCopy
传递给从 Stream(RetrieveDateFromFile
) 检索一些数据的方法时,readerCopy
和 reader
的资源在方法结束后被丢弃。因此,当我的调用方法稍后尝试使用 reader
时,它会抛出以下内容:
System.ObjectDisposedException: '无法访问已释放的对象。对象名称:'System.Net.Sockets.NetworkStream''
我认为将所有 Stream 对象封装在 using
语句中可以做到这一点,以便在到达这些语句的末尾之前不会释放资源,但看起来它们可能会被释放早点。
我错过了什么?
调用方式:
public void FtpFile()
{
// Gets the FTP data stream and stores it into reader, creates a new Stream object called readercopy.
using (Stream reader = request.GetResponse().GetResponseStream(), readerCopy = new MemoryStream())
{
if (reader != null)
{
reader.CopyTo(readerCopy);// Copies the original Stream to readerCopy.
readerCopy.Position = 0; //Sets the position to be beginning of the Stream.
SMDPPITrigger trigger = new SMDPPITrigger(); //Custom class
using (StreamReader fileReader = new StreamReader(readerCopy))
{
using (FileStream fileStream = new FileStream(ftpFileDestination, FileMode.Create))
{
if (trigger.CheckIfExists(RetrieveDateFromFile(fileReader)) == false)
while (true)
{
bytesRead = reader.Read(buffer, 0, buffer.Length); //<--- error occurs here.
if (bytesRead == 0)
break;
fileStream.Write(buffer, 0, bytesRead);
}
}
}
}
}
}
从流中检索数据的方法:
public DateTime RetrieveDateFromFile(StreamReader mainframeFile)
{
string lineParsed = "";
// StreamReader fileReader = new StreamReader(mainframeFile);
for (int i = 0; i <= 2; i++)
switch (i)
{
case 2:
string line = mainframeFile.ReadLine();
if (line != null)
{
lineParsed = line.Substring(124);
break;
}
else
{
break;
}
default:
{
mainframeFile.ReadLine();
break;
}
}
return DateTime.Parse(lineParsed);
}
我怀疑是以下两行代码导致了问题。
reader.CopyTo(readerCopy);// Copies the original Stream to readerCopy.
readerCopy.Position = 0; //Sets the position to be beginning of the Stream.
您可以尝试指定要复制到 readerCopy 中的流的长度吗?
例如
reader.CopyTo(readerCopy,124);
结束我的问题的循环。事实证明,问题和解决方案正是@KlausGütter 所说的。使用 reader.CopyTo(readerCopy)
将我的位置设置到流的末尾,我的错误消息不是它已被处理而是没有任何内容可读。使用我复制到的流,readerCopy
,解决了我的问题,因为流是可搜索的。
我有一些代码,我试图在从主机下载大型机文件之前读取其中的一行。我创建了一个 Stream class 的实例作为一个名为 reader
的对象,从主机检索 FTP 数据流并将其放入 Stream 对象,然后创建原始副本Stream 对象及其数据到另一个名为 readerCopy
的 Stream 对象中。我认为,我的问题是,当我将 readerCopy
传递给从 Stream(RetrieveDateFromFile
) 检索一些数据的方法时,readerCopy
和 reader
的资源在方法结束后被丢弃。因此,当我的调用方法稍后尝试使用 reader
时,它会抛出以下内容:
System.ObjectDisposedException: '无法访问已释放的对象。对象名称:'System.Net.Sockets.NetworkStream''
我认为将所有 Stream 对象封装在 using
语句中可以做到这一点,以便在到达这些语句的末尾之前不会释放资源,但看起来它们可能会被释放早点。
我错过了什么?
调用方式:
public void FtpFile()
{
// Gets the FTP data stream and stores it into reader, creates a new Stream object called readercopy.
using (Stream reader = request.GetResponse().GetResponseStream(), readerCopy = new MemoryStream())
{
if (reader != null)
{
reader.CopyTo(readerCopy);// Copies the original Stream to readerCopy.
readerCopy.Position = 0; //Sets the position to be beginning of the Stream.
SMDPPITrigger trigger = new SMDPPITrigger(); //Custom class
using (StreamReader fileReader = new StreamReader(readerCopy))
{
using (FileStream fileStream = new FileStream(ftpFileDestination, FileMode.Create))
{
if (trigger.CheckIfExists(RetrieveDateFromFile(fileReader)) == false)
while (true)
{
bytesRead = reader.Read(buffer, 0, buffer.Length); //<--- error occurs here.
if (bytesRead == 0)
break;
fileStream.Write(buffer, 0, bytesRead);
}
}
}
}
}
}
从流中检索数据的方法:
public DateTime RetrieveDateFromFile(StreamReader mainframeFile)
{
string lineParsed = "";
// StreamReader fileReader = new StreamReader(mainframeFile);
for (int i = 0; i <= 2; i++)
switch (i)
{
case 2:
string line = mainframeFile.ReadLine();
if (line != null)
{
lineParsed = line.Substring(124);
break;
}
else
{
break;
}
default:
{
mainframeFile.ReadLine();
break;
}
}
return DateTime.Parse(lineParsed);
}
我怀疑是以下两行代码导致了问题。
reader.CopyTo(readerCopy);// Copies the original Stream to readerCopy.
readerCopy.Position = 0; //Sets the position to be beginning of the Stream.
您可以尝试指定要复制到 readerCopy 中的流的长度吗? 例如
reader.CopyTo(readerCopy,124);
结束我的问题的循环。事实证明,问题和解决方案正是@KlausGütter 所说的。使用 reader.CopyTo(readerCopy)
将我的位置设置到流的末尾,我的错误消息不是它已被处理而是没有任何内容可读。使用我复制到的流,readerCopy
,解决了我的问题,因为流是可搜索的。