Stream 在 EndOfData 为真之前处理
Stream is disposing before EndOfData is true
我正在编写一个连接到 FTP 的方法,将 csv 文件读入流中,然后使用 TextFieldParser 处理数据。
除了在读取 CSV 进行到一半时突然遇到一个 ObjectDisposedException 异常外,一切正常。我试过将 StreamReader 和 TextReader 都传递给 TextFieldParser,但两者都会导致同样的问题。
我应该将 CSV 下载到临时本地目录然后读取它,还是从 FTP 读取文件没有问题?我认为可能有一些服务器设置可能会在读取整个文件之前使流超时。
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("REMOVED.csv");
request.Credentials = new NetworkCredential("xyz", "*******");
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (TextReader reader = new StreamReader(stream))
{
using (TextFieldParser parser = new TextFieldParser(reader))
{
parser.HasFieldsEnclosedInQuotes = true;
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData) //exception is thrown here about 1500lines into csv
{
Console.WriteLine(parser.ReadLine().ToString());
}
}
}
}
}
LAST LINE OF OUTPUT BEFORE EXCEPTION THROWN
190500,Courier Delivery,Freight,Distributor,1,5,15/12/2014 16:44
如果我应该先下载文件,我只使用 WebClient.DownloadFile() 吗??我如何知道文件何时完成下载然后读取它?
编辑:
系统网络跟踪输出显示如下
System.Net.Sockets Verbose: 0 : [10412] Exiting Socket#24914721::Receive() -> Int32#95
System.Net Information: 0 : [10412] FtpControlStream#15315213 - Received response [226-File successfully transferred
226 5.748 seconds (measured here), 30.91 Kbytes per second]
System.Net Information: 0 : [10412] FtpWebRequest#16868352::(Releasing FTP connection#15315213.)
进一步编辑
System.NetTracing 的输出显示了正在接收的 CSV 的最后一行,那么为什么解析器在完成之前就被处置了?我对编程还是很陌生,所以我不太确定如何进行
因此,在使用 TextFieldParser 读到最后之前,我无法弄清楚如何停止流处理,而是执行了以下操作:
Connect to FTP
Read the file into a stream
Copy the stream to a FileStream and create a temporary file
Read the temporary file
Delete the temporary file
这不是很优雅,但如果其他人遇到上述错误,请知道下载文件是一种替代方法。
Use the Peek method instead of EndOfData - havent tested this, but should work...
//...
using (var response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
while (reader.Peek() != -1) //use Peek instead
{
Console.WriteLine(reader.ReadLine());
}
}
}
}
//...
我正在编写一个连接到 FTP 的方法,将 csv 文件读入流中,然后使用 TextFieldParser 处理数据。
除了在读取 CSV 进行到一半时突然遇到一个 ObjectDisposedException 异常外,一切正常。我试过将 StreamReader 和 TextReader 都传递给 TextFieldParser,但两者都会导致同样的问题。
我应该将 CSV 下载到临时本地目录然后读取它,还是从 FTP 读取文件没有问题?我认为可能有一些服务器设置可能会在读取整个文件之前使流超时。
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("REMOVED.csv");
request.Credentials = new NetworkCredential("xyz", "*******");
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (TextReader reader = new StreamReader(stream))
{
using (TextFieldParser parser = new TextFieldParser(reader))
{
parser.HasFieldsEnclosedInQuotes = true;
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData) //exception is thrown here about 1500lines into csv
{
Console.WriteLine(parser.ReadLine().ToString());
}
}
}
}
}
LAST LINE OF OUTPUT BEFORE EXCEPTION THROWN
190500,Courier Delivery,Freight,Distributor,1,5,15/12/2014 16:44
如果我应该先下载文件,我只使用 WebClient.DownloadFile() 吗??我如何知道文件何时完成下载然后读取它?
编辑:
系统网络跟踪输出显示如下
System.Net.Sockets Verbose: 0 : [10412] Exiting Socket#24914721::Receive() -> Int32#95 System.Net Information: 0 : [10412] FtpControlStream#15315213 - Received response [226-File successfully transferred 226 5.748 seconds (measured here), 30.91 Kbytes per second] System.Net Information: 0 : [10412] FtpWebRequest#16868352::(Releasing FTP connection#15315213.)
进一步编辑
System.NetTracing 的输出显示了正在接收的 CSV 的最后一行,那么为什么解析器在完成之前就被处置了?我对编程还是很陌生,所以我不太确定如何进行
因此,在使用 TextFieldParser 读到最后之前,我无法弄清楚如何停止流处理,而是执行了以下操作:
Connect to FTP Read the file into a stream Copy the stream to a FileStream and create a temporary file Read the temporary file Delete the temporary file
这不是很优雅,但如果其他人遇到上述错误,请知道下载文件是一种替代方法。
Use the Peek method instead of EndOfData - havent tested this, but should work...
//...
using (var response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
while (reader.Peek() != -1) //use Peek instead
{
Console.WriteLine(reader.ReadLine());
}
}
}
}
//...