在 C#/Core MVC 中上传和解析 csv 文件

Uploading and parsing a csv file in C#/Core MVC

我尝试使用以下代码来解析正在上传的 CSV 文件:

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;
}

您会注意到我将上传流的路径而不是流本身传递给解析器。我尝试传入流,但这也不起作用。当我签入 wwwroot/WeeklySchedules 时,文件就在那里。但是当解析器到达它时,它返回为空。我什至加入了一个 Sleep() 来查看我是否过早地点击了文件。但这没有任何区别。

原始流出现一些奇怪的错误,但文件已写入,这让我感到困惑。

错误是:

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

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

我已经阅读了很多关于 loading/parsing CSV 文件技术的博客文章和 SO 问题,但其中 none 表明这是一个问题。

有没有人有什么想法?

通过文件保存代码;解开 2 using 语句,以确保在解析器开始读取文件之前文件已完全写入并正确关闭。

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

您的第一个文件流在您第一次使用时仍处于打开状态,您尝试使用 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;
    }