Читать запись фиксированной ширины из текстового файла
У меня есть текстовый файл, полный записей, где каждое поле в каждой записи имеет фиксированную ширину. Мой первый подход заключается в том, чтобы проанализировать каждую запись, просто используя 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 ответов
Подстрока звучит хорошо для меня. Единственный недостаток, о котором я могу сразу подумать, это то, что это означает копирование данных каждый раз, но я не буду беспокоиться об этом, пока вы не докажете, что это узкое место. Подстрока простая:)
Вы можете использовать регулярное выражение для сопоставления целой записи за раз и захвата полей, но я думаю, это было бы излишним.
Используйте 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);
Зачем изобретать велосипед? Используйте класс.NET TextFieldParser в соответствии с этим руководством для Visual Basic.
Возможно, вам придется остерегаться, если конец строк не заполнен пробелами для заполнения поля, ваша подстрока не будет работать без небольшого переворота, чтобы выяснить, сколько еще строк нужно прочитать. Это, конечно, относится только к последнему полю:)
К сожалению, из коробки CLR предоставляет только Substring для этого.
Кто-то из CodeProject создал собственный синтаксический анализатор, использующий атрибуты для определения полей, возможно, вы захотите посмотреть на это.
Вы можете настроить источник данных ODBC для файла с фиксированным форматом, а затем получить к нему доступ, как к любой другой таблице базы данных. Это дает дополнительное преимущество, заключающееся в том, что определенные знания о формате файла не скомпилированы в ваш код в тот роковой день, когда кто-то решит вставить дополнительное поле посередине.