如何在FileHelpers中使用动态CSV分隔符?

Ste*_*ger 2 .net c# csv filehelpers code-generation

问题:我需要阅读CSV文件.我使用FileHelpers库来实现这一点.

问题是我需要一个动态分隔符(用户定义),这意味着任何东西都可以是分隔符(逗号,分号,制表符,换行符,还有其他任何东西).

问题是,FileHelpers在属性中定义了分隔符,这意味着在编译时.这使得它无法动态地完成.

我能做的是声明一个新类,它继承自一个基类,并在这个新类上设置分隔符.

[FileHelpers.DelimitedRecord(",")]
public class CommaCustomer : BaseCustomer
{

}
Run Code Online (Sandbox Code Playgroud)

这样我只需要在每个新分隔符的基类中进行更改.问题是,这是我不能(也不想)为每个可能的分隔符创建子类.

这是我到目前为止的代码:

using System;
using System.Data;
using System.IO;
//using FileHelpers;
//using FileHelpers.RunTime;


namespace Examples
{


    class MainClass
    {


        [STAThread]
        static void Main()
        {
            FileHelpers.FileHelperEngine engine = new FileHelpers.FileHelperEngine(typeof(SemicolonCustomer));

            // To read use:

            string str = @"D:\Username\Desktop\FileHelpers_Examples_CSharp_VbNet\Data\SemicolonCustomers.txt";
            //str = @"D:\Username\Desktop\FileHelpers_Examples_CSharp_VbNet\Data\CustomersDelimited.txt";
            SemicolonCustomer[] custs = (SemicolonCustomer[])engine.ReadFile(str);
            //Customer[] custs = (Customer[]) engine.ReadFile("yourfile.txt");


            foreach (SemicolonCustomer cli in custs)
            {
                Console.WriteLine();
                Console.WriteLine("Customer: " + cli.CustId.ToString() + " - " + cli.Name);
                Console.WriteLine("Added Date: " + cli.AddedDate.ToString("d-M-yyyy"));
                Console.WriteLine("Balance: " + cli.Balance.ToString());
                Console.WriteLine();
                Console.WriteLine("-----------------------------");
            } // Next cli

            Console.ReadKey();
            Console.WriteLine("Writing data to a delimited file...");
            Console.WriteLine();


            // To write use:
            //engine.WriteFile("myyourfile.txt", custs);


            //If you are using .NET 2.0 or greater is 
            //better if you use the Generics version:

            // FileHelperEngine engine = new FileHelperEngine<Customer>();

            // To read use (no casts =)
            // Customer[] custs = engine.ReadFile("yourfile.txt");

            // To write use:
            // engine.WriteFile("yourfile.txt", custs);

        } // End Sub Main


    } // End Class  MainClass


    //------------------------
    //   RECORD CLASS (Example, change at your will)
    //   TIP: Remember to use the wizard to generate this class
    public class BaseCustomer
    {
        public int CustId;

        public string Name;
        public decimal Balance;
        [FileHelpers.FieldConverter(FileHelpers.ConverterKind.Date, "ddMMyyyy")]
        public DateTime AddedDate;
    }


    [FileHelpers.DelimitedRecord(";")]
    public class SemicolonCustomer : BaseCustomer
    {

    }


    [FileHelpers.DelimitedRecord(",")]
    public class CommaCustomer : BaseCustomer
    {

    }


}
Run Code Online (Sandbox Code Playgroud)

是否有可能在运行时编译子类

[FileHelpers.DelimitedRecord(\"" + delimiter + "\")]
public class AnyDelimiterCustomer : BaseCustomer
{           
}
Run Code Online (Sandbox Code Playgroud)

然后在代码中引用这个运行时编译的类?

sha*_*p00 17

我刚刚意识到有DelimitedFileEngine一种方法可以用另一种方式解决你的问题.

你可以去

var engine = new DelimitedFileEngine(typeof(BaseCustomer));
engine.Options.Delimiter = ",";
Run Code Online (Sandbox Code Playgroud)

似乎BaseCustomer需要使用[DelimitedRecord]属性进行修饰,否则会引发异常但是分隔符会被提供的内容覆盖engine.Options.Delimiter.

以下示例使用标记为bar分隔的格式导入逗号分隔的记录.

[DelimitedRecord("|")]
public class Format1
{
    public string Field1;           
    public string Field2;            
    public string Field3;            
    public string Field4;
}

static void Main(string[] args)
{
    var engine = new DelimitedFileEngine(typeof(Format1));
    // change the delimiter
    engine.Options.Delimiter = ","; 

    // import a comma separated record
    object[] importedObjects = engine.ReadString(@"a,b,c,d");

    foreach (object importedObject in importedObjects)
    {
        if (importedObject is Format1)
        {
            Format1 format1 = (Format1)importedObject;
            // process it (for example, check the values)
            Assert.AreEqual("a", format1.Field1);
            Assert.AreEqual("b", format1.Field2);
            Assert.AreEqual("c", format1.Field3);
            Assert.AreEqual("d", format1.Field4);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)