2008-10-02 3 views
17

У меня есть текстовый файл, полный записей, где каждое поле в каждой записи является фиксированной шириной. Моим первым подходом было бы проанализировать каждую запись, просто используя string.Substring(). Есть ли способ лучше?Чтение записи фиксированной ширины из текстового файла

Например, формат может быть описан как:

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

И пример файла с двумя записями может выглядеть следующим образом:

SomeData000000000SomeMoreData 
Data2 0000000000555555MoreData  

Я просто хочу, чтобы убедиться, что я не обойдена более элегантный способ, чем подстрока().


Update: я в конце концов пошел с регулярным выражением, как 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; 

ответ

5

Подстрока звучит хорошо для меня. Единственный недостаток, о котором я могу сразу подумать, состоит в том, что он означает копирование данных каждый раз, но я бы не стал беспокоиться об этом, пока не докажу, что это узкое место. Подстрока проста :)

может использовать регулярное выражение для соответствия целой записи за один раз и захватить поля, но я думаю, что это было бы излишним.

+0

Да, я пытался подумать о способе использования регулярного выражения, но думаю, что это неправильный инструмент для работы, и, как вы сказали, перебор. – 2008-10-02 14:59:24

+0

regex?^(. {8}) (. {16}) (. *) $ Для указанного определения полей, считая, что последнее поле может быть или не быть дополнено пробелами. – Sekhat 2008-10-02 15:01:51

1

Неа, Substring отлично , Вот для чего это.

2

Возможно, вам придется следить, если конец строк не заполняется пробелами, чтобы заполнить поле, ваша подстрока не будет работать без лишней игры, чтобы определить, насколько больше линии там читать. Это, конечно, относится только к последнему полю :)

21

Использование 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

Вы можете настроить источник данных ODBC для файла фиксированного формата и получить к нему доступ как любую другую таблицу базы данных. Это дает дополнительное преимущество в том, что определенные знания формата файла не скомпилированы в ваш код за тот роковой день, когда кто-то решает вставить дополнительное поле посередине.

Смежные вопросы