从文本文件中读取固定宽度记录

时间:2008-10-02 14:49:29

标签: c# .net parsing fixed-width

我有一个充满记录的文本文件,其中每个记录中的每个字段都是固定宽度。我的第一种方法是使用string.Substring()解析每条记录。有没有更好的办法?

例如,格式可以描述为:

<Field1(8)><Field2(16)><Field3(12)>

包含两条记录的示例文件可能如下所示:

SomeData0000000000123456SomeMoreData
Data2   0000000000555555MoreData    

我只是想确保我没有忽略比Substring()更优雅的方式。


更新:我最终选择了Killersponge建议的正则表达式:

private readonly Regex reLot = new Regex(REGEX_LOT, RegexOptions.Compiled);
const string REGEX_LOT = "^(?<Field1>.{6})" +
                        "(?<Field2>.{16})" +
                        "(?<Field3>.{12})";

然后我使用以下内容访问字段:

Match match = reLot.Match(record);
string field1 = match.Groups["Field1"].Value;

7 个答案:

答案 0 :(得分:26)

使用FileHelpers

示例:

[FixedLengthRecord()] 
public class MyData
{ 
  [FieldFixedLength(8)] 
  public string someData; 

  [FieldFixedLength(16)] 
  public int SomeNumber; 

  [FieldFixedLength(12)] 
  [FieldTrim(TrimMode.Right)]
  public string someMoreData;
}

然后,它就像这样简单:

var engine = new FileHelperEngine<MyData>(); 

// To Read Use: 
var res = engine.ReadFile("FileIn.txt"); 

// To Write Use: 
engine.WriteFile("FileOut.txt", res); 

答案 1 :(得分:6)

为什么重新发明轮子?按照此TextFieldParser使用.NET的how-to for Visual Basic类。

答案 2 :(得分:5)

子串对我来说听起来不错。我可以立即想到的唯一缺点是它意味着每次都要复制数据,但在你证明它是瓶颈之前我不会担心。子串很简单:)

可以使用正则表达式一次匹配整个记录并捕获字段,但我认为这样会有点过分。

答案 3 :(得分:2)

你可能需要注意,如果线的末端没有填充空格以填充字段,那么你的子字符串将无法工作而不需要花费一些时间来计算出更多的线阅读。这当然只适用于最后一个字段:)

答案 4 :(得分:1)

不幸的是,开箱即用的CLR只为此提供了子串。

Someone over at CodeProject made a custom parser using attributes to define fields,你可能想看一下。

答案 5 :(得分:0)

不,Substring很好。这就是它的用途。

答案 6 :(得分:0)

您可以为固定格式文件设置ODBC数据源,然后将其作为任何其他数据库表进行访问。 这有一个额外的好处,即文件格式的特定知识不会编译到您的代码中,因为有人决定在中间添加额外的字段。