0

I have the following code that I'm trying to use to parse a CSV file that is being uploaded:

private Dictionary<string, string[]> LoadData(IFormFile file) 
{
    // Verify that the user selected a file
    if (file != null && file.Length > 0) 
    {
        string wwwPath = this.environment.WebRootPath;
        // string contentPath = this.environment.ContentRootPath;

        string path = Path.Combine(wwwPath, "WeeklySchedules");

        if (!Directory.Exists(path)) 
        {
            Directory.CreateDirectory(path);
        }

        string fileName = Path.GetFileName(file.FileName);

        using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create)) 
        {
            file.CopyTo(stream);

            // System.Threading.Thread.Sleep(1000);
            using (TextFieldParser parser = new TextFieldParser(Path.Combine(path, fileName))) 
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");

                Dictionary<string, string[]> parsedData = new Dictionary<string, string[]>();

                while (!parser.EndOfData) 
                {
                    // Process row
                    string[] fields = parser.ReadFields();
                    int count = 0;

                    if (count++ == 0) 
                    {
                        continue;
                    }

                    var pickup = fields[0]; 
                    var pickupDate = fields[1];
                    var dropoff = fields[2];
                    var dropoffDate = fields[3];
                    var driver = fields[7];

                    var pickupTime = DateTime.Parse(pickupDate).ToLongTimeString();
                    // string[] data = 
                }
            }
        }
    }

    return null;
}

You will note that I am passing the path to the uploaded stream to the parser, rather than the stream itself. I tried passing in the stream, but that doesn't work either. When I check in wwwroot/WeeklySchedules, the file is there. But when the parser gets to it, it comes back as empty. I even threw in a Sleep() to see if I was just hitting the file too soon. But that didn't make any difference.

I am getting some weird errors with the original stream, but the file is written, which is puzzling to me.

The errors are:

stream.ReadTimeout = 'stream.ReadTimeout' threw an exception of type 'System.InvalidOperationException'

stream.WriteTimeout = 'stream.WriteTimeout' threw an exception of type 'System.InvalidOperationException'

I've read through a bunch of blog posts and SO questions on the technique for loading/parsing a CSV file, but none of them indicate this as an issue.

Does anyone have any ideas?

2 Answers 2

2

Your first file stream is still open in your first using and you try to read it again with TextFieldParser

    private Dictionary<string, string[]> LoadData(IFormFile file)
    {
        // Verify that the user selected a file
        if (file != null && file.Length > 0)
        {
            string wwwPath = this.environment.WebRootPath;
            // string contentPath = this.environment.ContentRootPath;

            string path = Path.Combine(wwwPath, "WeeklySchedules");

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            string fileName = Path.GetFileName(file.FileName);

            using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create))
            {
                file.CopyTo(stream);
            }

            // System.Threading.Thread.Sleep(1000);
            using (TextFieldParser parser = new TextFieldParser(Path.Combine(path, fileName)))
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");

                Dictionary<string, string[]> parsedData = new Dictionary<string, string[]>();

                while (!parser.EndOfData)
                {
                    // Process row
                    string[] fields = parser.ReadFields();
                    int count = 0;

                    if (count++ == 0)
                    {
                        continue;
                    }

                    var pickup = fields[0];
                    var pickupDate = fields[1];
                    var dropoff = fields[2];
                    var dropoffDate = fields[3];
                    var driver = fields[7];

                    var pickupTime = DateTime.Parse(pickupDate).ToLongTimeString();
                    // string[] data = 
                }
            }
        }

        return null;
    }

Sign up to request clarification or add additional context in comments.

1 Comment

That was it. Thanks a bunch!
1

Preserving your code going via a file; untangle the 2 using statements, to ensure the file has been written completely and has been closed properly, before the parser starts reading it.

using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create)) 
{
    file.CopyTo(stream);
}
    
using (TextFieldParser parser = new TextFieldParser(Path.Combine(path, fileName))) 
{
    // ..
}

1 Comment

D'oh. That was it! Works like a champ. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.