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

问题描述 投票:0回答:8

我有一个充满记录的文本文件,其中每个记录中的每个字段都是固定宽度。 我的第一种方法是简单地使用 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;
c# .net parsing fixed-width
8个回答
34
投票

使用文件助手

示例:

[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); 

8
投票

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

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


8
投票

为什么要重新发明轮子?根据 Visual Basic 的操作方法,使用 .NET 的 TextFieldParser 类:如何从固定宽度文本文件中读取


2
投票

您可能需要注意,如果行尾没有用空格填充来填充字段,那么您的子字符串将无法工作,除非稍微调整一下来计算出还有多少行需要读取。这当然只适用于最后一个字段:)


1
投票

不幸的是,开箱即用的 CLR 仅为此提供子字符串。

CodeProject 的某人使用属性来定义字段制作了一个自定义解析器,您可能想看看。


0
投票

不,子字符串就可以了。这就是它的用途。


0
投票

您可以为固定格式文件设置一个 ODBC 数据源,然后像访问任何其他数据库表一样访问它。 这样做的另一个优点是,在有人决定在中间添加额外字段的那一天,文件格式的特定知识不会编译到您的代码中。


0
投票

有为此目的的开源 .Net 库:
https://github.com/borisdj/FixedWidthParserWriter/
PS我是作者。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.