C# Stream disposed before ending parsing and readi

2019-08-15 05:11发布

问题:

I am reading a CSV file from an FTP server and parsing it on the fly.

However, I stumbled upon System.ObjectDisposedException in the middle of the file being read. I know for granted that the file is being read, since my console is already giving me output.

Most of the answers I found online are regarding people closing the stream/parser before the reading is completed, but I cannot see such a mistake in my code.

Here is the problematic method:

public static void readCSVfromFTP(string ftpFileAddress)
    {
        // Setup FTP Request
        FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(ftpFileAddress);
        ftpRequest.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
        ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
        FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();

        // Setup Response Stream & encoding
        Stream responseStream = response.GetResponseStream();

        // Text parser
        using (TextFieldParser parser = new TextFieldParser(responseStream))
        {
            // Text parser settings
            parser.SetDelimiters(new string[] { "," });
            parser.HasFieldsEnclosedInQuotes = false;

            // Text tokenization logic & file parsing
            while (!parser.EndOfData)
            {
                // Define columns
                string[] fields = parser.ReadFields();
                //int eanNumber = int.Parse(fields[0]);
                //int catalogueNumber = int.Parse(fields[1]);
                //double quantity = double.Parse(fields[2]);
                //DateTime availibilityDate = Convert.ToDateTime(fields[3]);
                Console.WriteLine(fields[0] + " " + fields[1]); 
            }
        }

        // Clean up and close streams
        responseStream.Close();
        response.Close();
    }

I should add, that the line which error highlights is:

while (!parser.EndOfData)

EDIT:

I have found a question with the exact same problem, yet it is unanswered. Unfortunately, their solution doesn't satisfy me.

回答1:

Once there is no more data available, the value returned from parser.ReadFields() becomes nothing / null. So a workaround is to replace the while (!parser.EndOfData) with a While (true) and then each iteration check if fields is null, exiting the loop early if it is.

In Visual Basic it looks like this:

While True
            Try
                currentRow = MyReader.ReadFields()
                If currentRow Is Nothing Then
                    Exit While
                End If
                'Now do everything else
            End Try
        End While

I'm no expert on C# ( or VB for that matter), even so I'll hazard a guess that the C# equivalent would look something like:

while (true)
        {
            // Define columns
            string[] fields = parser.ReadFields();
            if (fields == null){
               break;
               } 
            //int eanNumber = int.Parse(fields[0]);
            //int catalogueNumber = int.Parse(fields[1]);
            //double quantity = double.Parse(fields[2]);
            //DateTime availibilityDate = Convert.ToDateTime(fields[3]);
            Console.WriteLine(fields[0] + " " + fields[1]); 
        }

Perhaps someone with a bit more familiarity with it might be kind enough to fix any syntax errors in the above.

As @casperOne says the real answer would be within the source of TextFieldParser - this looks like a bug to me.