首页 > 解决方案 > 上传后使用块和删除文件时封闭 csv.Reader 的问题

问题描述

将其内容导入数据库后,我需要删除我的 csv 文件。当我尝试这样做时,我得到一个 system.io 异常,说该文件正在被另一个进程使用。我曾尝试将读取内容包含在 using 块中,但文件不会被读取到我的目标 IEnumerable。我的代码如下 - 非常感谢任何帮助解决这个问题。

当我调用 csv.Read 在 using 块中生成 learningTasksList 时, learningTasksList 为空。但是,如果我省略 using 块 - 如下面未注释掉的代码中所示,则会正确填充learingTasksList。但是,我得到了对象列表,但该过程没有被处理掉,之后我无法删除文件上传的文件

private IEnumerable<LearningTask> GenerateNewLearningTasksList(string filePathToImport)
    {


        //using (var reader = new StreamReader(filePathToImport))
        //using (var csv = new CsvReader(reader))
        //{
        //    csv.Configuration.HeaderValidated = null;  
        //    csv.Configuration.MissingFieldFound = null;  

        //    try
        //    {
        //        var learningTasksList = csv.GetRecords<LearningTask>();
        //        return learningTasksList;
        //    }
        //    catch (Exception ex)
        //    {
        //        Log.Error("Error generating list of new Learning Tasks from csv  - {Error}", ex.InnerException);
        //        return null;
        //    }
        //}


        //This works but I am unable to dispose of it after I have transferred the records to learningTasksList
        var reader = new StreamReader(filePathToImport);
        var csv = new CsvReader(reader);
        csv.Configuration.HeaderValidated = null;  
        csv.Configuration.MissingFieldFound = null; 

        try
        {
            var learningTasksList = csv.GetRecords<LearningTask>();
            return learningTasksList;

        }
        catch (Exception ex)
        {
            Log.Error("Error generating list of new Learning Tasks from csv  - {Error}", ex.InnerException);
            return null;
        }

    }

标签: csvhelper

解决方案


从 CsvHelper入门页面。

GetRecords<T>方法将返回一个IEnumerable<T>yield记录的内容。这意味着在您迭代记录时一次只返回一条记录。这也意味着只有一小部分文件被读入内存。不过要小心。如果您执行任何执行 LINQ 投影的操作,例如调用.ToList(),则整个文件将被读入内存。

解决此问题的一种方法是从andToList()的 using 块中调用。StreamReaderCsvReader

var learningTasksList = csv.GetRecords<LearningTask>().ToList();

如果您不想一次将整个文件读入内存,则必须将 传递CsvReader给您的方法,然后在完成枚举后GenerateNewLearningTasksList()关闭与 的连接。StreamReaderlearningTasksList


推荐阅读