2011-02-17 58 views
5

我想导入一个文件,其中有多个记录定义。每个人也可以有一个标题记录,所以我想我会像这样定义一个定义界面。使用泛型类定义导入数据文件

public interface IRecordDefinition<T> 
{ 
    bool Matches(string row); 
    T MapRow(string row); 
    bool AreRecordsNested { get; } 
    GenericLoadClass ToGenericLoad(T input); 
} 

然后我创建了一个类的具体实现。

public class TestDefinition : IRecordDefinition<Test> 
{ 
    public bool Matches(string row) 
    { 
     return row.Split('\t')[0] == "1"; 
    } 

    public Test MapColumns(string[] columns) 
    { 
     return new Test {val = columns[0].parseDate("ddmmYYYY")}; 
    } 

    public bool AreRecordsNested 
    { 
     get { return true; } 
    } 

    public GenericLoadClass ToGenericLoad(Test input) 
    { 
     return new GenericLoadClass {Value = input.val}; 
    } 
} 

但是为每个文件定义我需要存储的记录定义的列表,这样我就可以再通过该文件,并进行相应的处理中的每一行循环。

首先,我在正确的轨道上
还是有更好的方法来做到这一点?

+1

您是否想发布任何示例文件以使示例更具体? – 2011-02-17 01:33:48

+1

什么是源数据?文本? CSV?二进制?以上任何一项? – 2011-02-20 01:15:37

回答

3

你看过什么用Linq?这是Linq to Text和Linq to Csv的一个简单例子。

我认为使用“yield return”和IEnumerable来得到你想要的工作会简单得多。通过这种方式,您可能只能在界面上使用1种方法。

3

我会将这个过程分成两部分。

首先,一个特定进程将文件分成多个文件。如果这些文件的宽度是固定的,那么我对正则表达式有很大的好运。例如,假设以下是具有三种不同记录类型的文本文件。

TE20110223 A 1 
RE20110223 BB 2 
CE20110223 CCC 3 

你可以看到这里有一个模式,希望的人谁决定把所有的记录类型在同一个文件给你一个方法来识别这些类型。在上面的例子中,你将定义三个正则表达式。

string pattern1 = @"^TE(?<DATE>[0-9]{8})(?<NEXT1>.{2})(?<NEXT2>.{2})"; 
string pattern2 = @"^RE(?<DATE>[0-9]{8})(?<NEXT1>.{3})(?<NEXT2>.{2})"; 
string pattern3 = @"^CE(?<DATE>[0-9]{8})(?<NEXT1>.{4})(?<NEXT2>.{2})"; 

Regex Regex1 = new Regex(pattern1); 
Regex Regex2 = new Regex(pattern2); 
Regex Regex3 = new Regex(pattern3); 

StringBuilder FirstStringBuilder = new StringBuilder(); 
StringBuilder SecondStringBuilder = new StringBuilder(); 
StringBuilder ThirdStringBuilder = new StringBuilder(); 

string Line = ""; 
Match LineMatch; 


FileInfo myFile = new FileInfo("yourFile.txt"); 

using (StreamReader s = new StreamReader(f.FullName)) 
{ 

    while (s.Peek() != -1) 
    { 
     Line = s.ReadLine(); 

     LineMatch = Regex1.Match(Line); 
     if (LineMatch.Success) 
     { 
      //Write this line to a new file 
     } 

     LineMatch = Regex2.Match(Line); 
     if (LineMatch.Success) 
     { 
      //Write this line to a new file 
     } 

     LineMatch = Regex3.Match(Line); 
     if (LineMatch.Success) 
     { 
      //Write this line to a new file 
     } 
    } 
} 

接下来,我们取分割文件,并通过通用过程中运行它们,你很可能已经具备,将其导入。这很好,因为当进程不可避免地失败时,你可以将它缩小到失败的单一记录类型,而不会影响所有记录类型。将主文本文件与分割文件一起归档,您的生活也将变得更加容易。

处理这些类型的传输文件很难,因为别人控制它们,你永远不知道它们什么时候会改变。记录原始文件以及收据的导入非常重要,不应该被忽视。你可以尽可能简单或复杂,但我倾向于将收据写入数据库并将该表中的主键复制到表中我已导入数据的外键中,然后从不更改该数据。我喜欢在文件系统和数据库服务器上保留一个不受干扰的导入副本,因为存在不可避免的转换/转换问题,您需要跟踪这些问题。

希望这会有所帮助,因为这不是一项简单的任务。我认为你在正确的轨道上,而不是单独处理/导入每一行......将它们写入单独的文件。我假设这是财务数据,这是我认为在每一步中可证明性都很重要的原因之一。