【问题标题】:How can one to dynamically parse a CSV file using C# and the Smart Format Detector in FileHelpers 3.1?如何使用 C# 和 FileHelpers 3.1 中的智能格式检测器动态解析 CSV 文件?
【发布时间】:2015-12-07 02:01:38
【问题描述】:

根据FileHelpers 3.1 example,您可以使用 FileHelpers.Detection.SmartFormatDetector 类自动检测 CSV 文件格式。

但是这个例子没有更进一步。您如何使用这些信息来动态解析 CSV 文件?它一定与 DelimitedFileEngine 有关,但我不知道如何。

更新:

我想出了一个可能的方法,但不得不求助于反射(感觉不对)。还有其他/更好的方法吗?也许使用 System.Dynamic?无论如何,这是我到目前为止的代码,它不是很漂亮,但它可以工作:

        // follows on from smart detector example

        FileHelpers.Detection.RecordFormatInfo lDetectedFormat = formats[0];

        Type lDetectedClass = lDetectedFormat.ClassBuilderAsDelimited.CreateRecordClass();

        List<FieldInfo> lFieldInfoList = new List<FieldInfo>(lDetectedFormat.ClassBuilderAsDelimited.FieldCount);
        foreach (FileHelpers.Dynamic.DelimitedFieldBuilder lField in lDetectedFormat.ClassBuilderAsDelimited.Fields)
            lFieldInfoList.Add(lDetectedClass.GetField(lField.FieldName));

        FileHelperAsyncEngine lFileEngine = new FileHelperAsyncEngine(lDetectedClass);
        int lRecNo = 0;
        lFileEngine.BeginReadFile(cReadingsFile);
        try
        {
            while (true)
            {
                object lRec = lFileEngine.ReadNext();
                if (lRec == null)
                    break;

                Trace.WriteLine("Record " + lRecNo);
                lFieldInfoList.ForEach(f => Trace.WriteLine("   " + f.Name + " = " + f.GetValue(lRec)));

                lRecNo++;
            }
        }
        finally
        {
            lFileEngine.Close();
        }

【问题讨论】:

  • 动态不只是意味着它使用了反射和后期绑定吗?反射总是会影响性能,因此唯一的其他方法是使用 Linq 表达式

标签: parsing csv dynamic flat-file filehelpers


【解决方案1】:

当我使用 SmartFormatDetector 来确定传入分隔文件的确切格式时,您可以使用以下方法:

    private DelimitedClassBuilder GetFormat(string file)
    {
        var detector = new FileHelpers.Detection.SmartFormatDetector();
        var format = detector.DetectFileFormat(file);

        return format.First().ClassBuilderAsDelimited;
    }

    private List<T> ConvertFile2Objects<T>(string file, out DelimitedFileEngine engine)
    {
        var format = GetSeperator(file); // Get Here your FormatInfo
        engine = new DelimitedFileEngine(typeof(T)); //define your DelimitdFileEngine

        //set some Properties of the engine with what you need
        engine.ErrorMode = ErrorMode.SaveAndContinue; //optional
        engine.Options.Delimiter = format.Delimiter;
        engine.Options.IgnoreFirstLines = format.IgnoreFirstLines;
        engine.Options.IgnoreLastLines = format.IgnoreLastLines;
        //process
        var ret = engine.ReadFileAsList(file);
        this.errorCount = engine.ErrorManager.ErrorCount;
        var err = engine.ErrorManager.Errors;
        engine.ErrorManager.SaveErrors("errors.out");
        //return records do here what you need
        return ret.Cast<T>().ToList();
    }

这是我在项目中使用的一种方法,我只知道我必须处理多种类型的分隔文件。

注意: 我注意到,对于我收到的文件,SmartFormatDetector 的制表符分隔符有问题。也许应该考虑一下。

免责声明:此代码尚未完善,但处于可用状态。建议修改和/或重构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2018-07-10
    相关资源
    最近更新 更多