代码之家  ›  专栏  ›  技术社区  ›  Falco

FlatFile库,分隔布局,行末多个字段为空时错误分析

c#
  •  1
  • Falco  · 技术社区  · 6 年前

    我们在一些应用程序中使用FlatFile库( https://github.com/forcewake/FlatFile )解析一些用分隔符(“;”)分隔的文件,因为很多时候没有问题。

    昨天,我们在接收行末尾有多个空字段的文件时遇到问题。

    using FlatFile.Delimited;
    using FlatFile.Delimited.Attributes;
    using FlatFile.Delimited.Implementation;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    
    namespace FlatFileTester
    {
        class Program
        {
            static void Main(string[] args)
            {
                var layout = GetLayout();
                var factory = new DelimitedFileEngineFactory();
    
                using (MemoryStream ms = new MemoryStream())
                using (FileStream file = new FileStream(@"D:\shared\dotnet\FlatFileTester\test.csv", FileMode.Open, FileAccess.Read))
                {
                    byte[] bytes = new byte[file.Length];
                    file.Read(bytes, 0, (int)file.Length);
                    ms.Write(bytes, 0, (int)file.Length);
                    var flatFile = factory.GetEngine(layout);
                    ms.Position = 0;
                    List<TestObject> records = flatFile.Read<TestObject>(ms).ToList();
    
                    foreach(var record in records)
                    {
                        Console.WriteLine(string.Format("Id=\"{0}\" - DescriptionA=\"{1}\" - DescriptionB=\"{2}\" - DescriptionC=\"{3}\"", record.Id, record.DescriptionA, record.DescriptionB, record.DescriptionC));
                    }
    
                }
                Console.ReadLine();
            }
    
            public static IDelimitedLayout<TestObject> GetLayout()
            {
                IDelimitedLayout<TestObject> layout = new DelimitedLayout<TestObject>()
                    .WithDelimiter(";")
                    .WithQuote("\"")
                    .WithMember(x => x.Id)
                    .WithMember(x => x.DescriptionA)
                    .WithMember(x => x.DescriptionB)
                    .WithMember(x => x.DescriptionC)
                    ;
    
                return layout;
            }
        }
    
        [DelimitedFile(Delimiter = ";", Quotes = "\"")]
        public class TestObject
        {
            [DelimitedField(1)]
            public int Id { get; set; }
    
            [DelimitedField(2)]
            public string DescriptionA { get; set; }
    
            [DelimitedField(3)]
            public string DescriptionB { get; set; }
    
            [DelimitedField(4)]
            public string DescriptionC { get; set; }
        }
    
    }
    

    这是一个文件示例:

    1;desc1;desc1;desc1
    2;desc2;desc2;desc2
    3;desc3;;desc3
    4;desc4;desc4;
    5;desc5;;
    

    • 第一行和第二行中有值的所有字段
    • 第三行第三个字段的空字符串
    • 第四行第四个字段的空字符串

    在第五行中,我们希望第三和第四个字段上有空字符串,如下所示:

    Id=5
    DescriptionA="desc5"
    DescriptionB=""
    DescriptionC=""
    

    Id=5
    DescriptionA="desc5"
    DescriptionB=";"        // --> THE SEPARATOR!!!
    DescriptionC=""
    

    我们无法理解是否是配置问题、库错误或代码中的其他问题。。。

    任何人对此库都有类似的经验,或者可以注意到上面代码中的一些问题,这些问题不是与库链接的,而是导致错误。。。?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Falco    6 年前

    我查看并调试了开源库的源代码: https://github.com/forcewake/FlatFile .

    似乎有一个问题,特别是在这种情况下,如果有两个空字段,那么在一行的末尾,bug会在最后一行之前对字段生效。

    我为这个图书馆打开了一个问题,希望图书馆的某个贡献者能花点时间来调查,如果是这样的话,可以修复: https://github.com/forcewake/FlatFile/issues/80

            string separator = ",";
            //...
            //...
            //...
            records.ForEach(x => {
                x.DescriptionC = x.DescriptionC.Replace(separator, "");
            });
    

    无论如何,对于我们的例子来说,有一个字符对应于分隔符作为该字段的值是没有意义的。。。

    …即使修复库中的错误会更好