我有一个充满记录的文本文件,其中每个记录中的每个字段都是固定宽度。 我的第一种方法是简单地使用 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;
使用文件助手。
示例:
[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);
子串对我来说听起来不错。我能立即想到的唯一缺点是,这意味着每次都要复制数据,但在你证明这是一个瓶颈之前,我不会担心这一点。子字符串很简单:)
您可以使用正则表达式一次匹配整个记录并捕获字段,但我认为这太过分了。
为什么要重新发明轮子?根据 Visual Basic 的操作方法,使用 .NET 的 TextFieldParser 类:如何从固定宽度文本文件中读取。
您可能需要注意,如果行尾没有用空格填充来填充字段,那么您的子字符串将无法工作,除非稍微调整一下来计算出还有多少行需要读取。这当然只适用于最后一个字段:)
不幸的是,开箱即用的 CLR 仅为此提供子字符串。
不,子字符串就可以了。这就是它的用途。
您可以为固定格式文件设置一个 ODBC 数据源,然后像访问任何其他数据库表一样访问它。 这样做的另一个优点是,在有人决定在中间添加额外字段的那一天,文件格式的特定知识不会编译到您的代码中。
有为此目的的开源 .Net 库:
https://github.com/borisdj/FixedWidthParserWriter/
PS我是作者。