Как лучше всего читать текстовый файл с разделителями табуляции на С#

У нас есть текстовый файл с примерно 100 000 строк, примерно 50 столбцов в строке, большая часть данных довольно мала (от 5 до 10 символов или цифр).

Это довольно простая задача, но просто интересно, как лучше всего импортировать эти данные в структуру данных C# (например, DataTable)?


person alchemical    schedule 26.01.2010    source источник
comment
Для 100 000 строк вы, вероятно, не хотите загружать их в DataTable. Возможно, вы захотите изучить использование SqlBulkCopy при вставке его в базу данных.   -  person Even Mien    schedule 27.01.2010


Ответы (6)


Я бы прочитал его как CSV с разделителями столбцов вкладок:

Быстрая программа для чтения CSV

Изменить.
Вот простой пример того, что вам нужно:

DataTable dt = new DataTable();
using (CsvReader csv = new CsvReader(new StreamReader(CSV_FULLNAME), false, '\t')) {
    dt.Load(csv);
}

Где CSV_FULLNAME — это полный путь + имя файла вашего CSV с разделителями табуляции.

person Jay Riggs    schedule 26.01.2010
comment
Я проверю, у кого-нибудь есть пример кода для его использования с разделителями столбцов табуляции? - person alchemical; 27.01.2010
comment
Я бы предложил пойти с чем-то вроде этого. Вы также можете использовать драйвер Access/Jet для доступа к ADO.Net, но иногда в этом есть некоторая причудливость. - person Tracker1; 27.01.2010
comment
@AirMan - я добавил простой образец. - person Jay Riggs; 27.01.2010
comment
Я реализовал это, и оно отлично работает, затем мне сказали, что корпоративная политика запрещает открытый исходный код, поэтому я собрал объект, который занимает в два раза больше времени. Fast CSV Reader кажется отличным способом, если вы можете — разработчик даже ответил на пару вопросов в течение нескольких минут. - person alchemical; 28.01.2010
comment
Есть ли разница в использовании CachedCsvReader для загрузки DataTable по сравнению с использованием CsvReader, поскольку DataTable все равно загружается в память, так зачем сначала использовать CachedCsvReader в памяти? - person Tim Schmelter; 28.06.2012
comment
@TimSchmelter Вы правы, CsvReader было бы лучше для ОП; CachedCsvReader предназначен для конкретных сценариев привязки данных и для небольших файлов данных. Спасибо, что указали на это, ответ обновлен. - person Jay Riggs; 29.06.2012

Используйте встроенный анализатор текста .NET. Он бесплатный, имеет отличную обработку ошибок и имеет дело с множеством странных случаев с мячом.

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser(VS.80).aspx

person Jonathan Allen    schedule 26.01.2010
comment
Нет, он просто оказался в пространстве имен VB, потому что его создала эта команда. Вы можете использовать его с любого языка .NET. - person Jonathan Allen; 27.01.2010

Что касается FileHelpers, вы можете определить вкладку как разделитель. Перейдите на этот сайт по предоставленной ссылке и посмотрите.

Надеюсь, это поможет. С уважением, Том.

person t0mm13b    schedule 26.01.2010

Два варианта:

  1. Используйте классы в пространстве имен System.Data.OleDb. Это имеет то преимущество, что вы читаете непосредственно в таблицу данных, как вы просили, с очень небольшим количеством кода, но это может быть сложно сделать правильно, потому что это табуляция, а не разделители-запятые.
  2. Используйте или напишите парсер csv. Убедитесь, что это синтаксический анализатор на основе конечного автомата, такой как тот, с которым связан @Jay Riggs, а не синтаксический анализатор на основе String.Split(). Это должно быть быстрее, чем метод OleDb, но он даст вам список или массив, а не таблицу данных.
person Joel Coehoorn    schedule 26.01.2010
comment
Просто любопытно, почему вы предлагаете синтаксический анализатор на основе состояния, а не String.Split(). - person Andy White; 27.01.2010
comment
Производительность, в основном. Но также и то, что с помощью string.split трудно получить такие вещи, как текст в кавычках. - person Joel Coehoorn; 27.01.2010
comment
Кроме того, под конечным автоматом я не подразумеваю Regex, что примерно так же плохо. Я имею в виду конечный автомат, специально созданный для этой задачи, который может лучше обрабатывать спуск/рекурсию. - person Joel Coehoorn; 27.01.2010

Как бы вы ни анализировали строки, убедитесь, что вы используете что-то, что поддерживает перемотку вперед и назад, являясь источником данных вашей сетки данных. Вы ведь не хотите сначала загрузить все в память, не так ли? Как насчет того, чтобы в следующий раз объем данных был десятикратным? Сделайте что-то, что использует file.seek в глубине души, не читайте сначала все в память. Это мой совет.

person Erik A. Brandstadmoen    schedule 26.01.2010

Простой, но не обязательно отличный способ:

  • Прочитайте файл с помощью программы чтения текста в строку

  • Используйте String.Split для получения строк

  • используйте String.Split с символом табуляции, чтобы получить значения поля

person Andrew Lewis    schedule 26.01.2010
comment
просто напомню об этом - есть string[] System.IO.File.ReadAllLines(string path) - person DK.; 27.01.2010