Чтение записи фиксированной ширины из текстового файла

У меня есть текстовый файл, полный записей, где каждое поле в каждой записи имеет фиксированную ширину. Моим первым подходом было бы проанализировать каждую запись, просто используя 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;

Можно использовать следующую библиотеку: https://github.com/borisdj/FixedWidthParserWriter

borisdj 20.11.2018 22:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
20
1
27 904
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Нет, подстрока в порядке. Вот для чего это нужно.

Ответ принят как подходящий

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

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

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

Chris Karcher 02.10.2008 18:59

регулярное выражение? ^ (. {8}) (. {16}) (. *) $ Для приведенного выше определения полей, предполагая, что последнее поле может или не может быть дополнено пробелами.

Sekhat 02.10.2008 19:01

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

Используйте 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); 

Для этого нужны какие-то дженерики, может, мне стоит взглянуть и сделать это: P

Sekhat 02.10.2008 20:18

-1 для решения, зависящего от внешней библиотеки, неоптимально.

Mark Rogers 31.12.2013 22:20

К сожалению, из коробки CLR предоставляет для этого только Substring.

Кто-то в CodeProject создал собственный парсер, используя атрибуты для определения полей., вы могли бы посмотреть на это.

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

Зачем изобретать велосипед? Используйте класс .NET TextFieldParser согласно этому руководству для Visual Basic: Как читать из текстовых файлов фиксированной ширины.

Другие вопросы по теме