从FileHelpers中解析值?或者这个程序功能

时间:2012-02-08 23:16:25

标签: c# .net filehelpers

我想知道我是否应该抛弃文件管理器并自行完成,因为我认为我可能会超出它的设计范围。

我希望用户能够上传任何csv文件(可能在将来的excel文件中)。第一行将有标题

C1 C2 C3 C4 C5 C6

一旦上传,它就像

C1,C2,C3,C4,C5,C6  A,B,C,d,E,F

现在我想查看标题并基本上采取某些标题。例如,我想要C2, C3, C4.其余的是我不关心的额外信息。

现在有人可能会上传包含此标题的文件

C1 C2 C3 C4

我再次只关注C2, C3, C4

我知道我可以有多种格式,但我得到的是我希望他们能够基本上传任何数量的标题文件(对于我所关心的所有文件都可以是1000)然后让我的应用程序尝试查找我关心的信息(所以在1000个标题的情况下我可能只想要3)

这可能吗?

修改

(基于shamp00评论)

我的目标是尽可能多地填写数据,但是这样的情况可能会发生。我想要C1,C2,C3。他们给出了一个带有C1,C3,C4的文件。我得到了我想要的2列数据,但我没有C2。

现在我有2个想法,就是将数据显示在2个表中。表1将包含C1,C2,C3和表2将具有C1,C3,C4,它们基本上采用表2中的数据并将适当的数据移动到我预期的列中。

通过这种方法,我基本上说“你没有给我100%的预期,现在你必须将每一行格式化为我的格式”。

第二种方法是1表,并尽量填写尽可能多的数据。

例如,用户上传具有C1,C3,C4的文件。我确定它们是已知的2列,但我还没有完整的预期数据。

所以我会将html表格中的所有行显示给标题为

的用户
C1, C2, C3, C4

C1将被填入,C2单元格将为空白(因为这是我从他们那里丢失的数据),C3将被填入,C4将被填入(这些数据是意外的,但谁知道它可能实际上是C2应该保留的数据,但由于它们错误拼写了标题名称,我的程序无法解决这个问题。)

然后基本上他们只会用他们从其他地方或者从C4获得的数据来填充C2。

现在他们只需填写1列而不是所有期望的列。所以在某种意义上我需要一个像MyClass这样的具体类,包括C1,C2,C3,但同时我需要动态,所以我可以保持C4,C5.....Cn

我会首先显示C1,C2,C3,其余的这些意想不到的东西会在javascript的魔力之后出现,他们可以编辑丢失的信息。如果没有遗漏任何东西,他们什么都不会被编辑。

基于shamp00注释我现在想知道是否需要将数据作为数据表返回(幸运的是,这似乎是一个系统类,因为我的代码在服务层中,我返回了一个域转移类因为我想保持我的代码独立于类似的Web代码类,因此我试图弄清楚如何生成动态类FileHelpers。)。

然后以某种方式(不是100%确定)只是跟踪那些我真正感兴趣的3列的位置,所以我知道哪些数据是什么。

2 个答案:

答案 0 :(得分:1)

您可以使用my answer to your other question中描述的技术使用FileHelpers。

您读取标题行以确定哪些列是相关的,然后遍历生成的DataTable仅处理那些列。

这样的东西
public class MyClass
{
    public string SomeImportantField { get; set; }
    public string SomeOtherField { get; set; }
    public string AnotherField { get; set; }
}

public IList<MyClass> GetObjectsFromStream(Stream stream)
{
    var cb = new DelimitedClassBuilder("temp", ",") { IgnoreFirstLines = 1, IgnoreEmptyLines = true, Delimiter = "," };
    var sr = new StreamReader(stream);
    var headerArray = sr.ReadLine().Split(',');
    foreach (var header in headerArray)
    {
        var fieldName = header.Replace("\"", "").Replace(" ", "");
        cb.AddField(fieldName, typeof(string));
    }

    var engine = new FileHelperEngine(cb.CreateRecordClass());

    List<MyClass> objects = new List<MyClass>();
    DataTable dt = engine.ReadStreamAsDT(sr);
    foreach (DataRow row in dt.Rows) // Loop over the rows.
    {
        MyClass myClass = new MyClass();
        for (int i = 0; i < row.ItemArray.Length; i++) // Loop over the items.
        {
            if (headerArray[i] == "ImportantField")
                myClass.SomeImportantField = row.ItemArray[i].ToString();
            if (headerArray[i] == "OtherField")
                myClass.SomeOtherField = row.ItemArray[i].ToString();
            if (headerArray[i] == "AnotherField")
                myClass.AnotherField = row.ItemArray[i].ToString();
            objects.Add(myClass);
        }
    }
    return objects;
}

答案 1 :(得分:1)

我不熟悉FileHelpers,但是我使用名为LogParser的工具(http://www.microsoft.com/download/en/details.aspx?displaylang=en& id = 24659)与我自己的“DelimitedTextFileData”类一起使用。如果您认为FileHelpers不会满足您的需求,我建议您下一步查看LogParser。即使它对您当前的项目来说太过分了,它也是了解未来项目的绝佳工具。

LogParser是一种允许针对各种来源(包括CSV文本文件)进行“类似SQL”查询的工具。它是一个基于命令行的.exe,但也附带了一个可以在.NET项目中引用的API。在我的情况下,我正在处理可以被任何字符分隔的文本文件,所以我开发了自己的类,让我在类实例化上指定分隔符,然后使用简单的API来挖掘更大的LogParser API。我还必须解析具有未知数量(和名称)列的文件,因此我的自定义类具有检索文件中找到的列列表的功能。如果您始终处理CSV,并且您确切知道所需的列,则可能不需要执行这些额外步骤。不过,如果你愿意,我很乐意分享我的定制课程;请告诉我发送它的最佳方式。

LogParser旨在让您“使用类似SQL的语法查询任何内容”,而且我想到Linq的一个目的是做同样的事情。您是否在线搜索过“Linq to Text File”库?如果那里有一个好的,它也可以解决你的问题。