Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
CSV импорт файлов в .Net
Я понимаю, что это вопрос новичка, но я ищу простое решение - кажется, что оно должно быть.
Как лучше всего поместить файл import a CSV в строго типизированную структуру данных? Опять же просто = лучше.
Microsoft TextFieldParser является стабильным и следует за RFC 4180 для CSV файлов. Не пугайтесь пространства имен Microsoft.VisualBasic ; это стандартный компонент в структуре .NET, просто добавьте ссылку на глобальный Microsoft.VisualBasic assembly.
Если вы компилируете для Windows (в отличие от Mono) и не ожидаете, что вам придется разбирать файлы "broken" (non-RFC-compliant) CSV, то это будет очевидный выбор, поскольку он свободен, неограничен, стабилен и активно поддерживается, большинство из которых нельзя сказать о FileHelpers.
См. также : Как читать из текстовых файлов с разделителями-запятыми в Visual Basic для примера кода VB.
Используйте соединение OleDB.
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\InputDirectory\\;Extended Properties='text;HDR=Yes;FMT=Delimited'";
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
DataTable dt = new DataTable();
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM file.csv", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
objAdapter1.Fill(dt);
objConn.Close();
Если вы ожидаете довольно сложных сценариев для парсинга CSV, даже не думайте о том, чтобы запустить наш собственный парсер . Есть много отличных инструментов, таких как FileHelpers , или даже из CodeProject .
Дело в том, что это довольно распространенная проблема, и вы можете поспорить, что многие разработчики программного обеспечения уже думали и решили эту проблему.
Я согласен с @ NotMyself . FileHelpers хорошо протестирован и обрабатывает все виды крайних случаев, с которыми вам в конечном итоге придется иметь дело, если вы сделаете это самостоятельно. Взгляните на то, что делает FileHelpers, и пишите только свои собственные, если вы абсолютно уверены, что либо (1) Вам никогда не нужно будет обрабатывать крайние случаи FileHelpers, либо (2) вы любите писать такие вещи и будете очень рады, когда вам придется разбирать такие вещи:
1,"Bill","Smith","Supervisor", "No Comment"
2 , 'Селезень' , 'O'Malley',"Дворник,
Ой, меня не цитируют, и я на новой линии!
Брайан дает хорошее решение для преобразования его в строго типизированную коллекцию.
Большинство приведенных методов синтаксического анализа CSV не учитывают экранирование полей или некоторые другие тонкости файлов CSV (например, обрезка полей). Вот код, который я лично использую. Он немного грубоват по краям и практически не содержит отчетов об ошибках.
public static IList<IList<string>> Parse(string content)
{
IList<IList<string>> records = new List<IList<string>>();
StringReader stringReader = new StringReader(content);
bool inQoutedString = false;
IList<string> record = new List<string>();
StringBuilder fieldBuilder = new StringBuilder();
while (stringReader.Peek() != -1)
{
char readChar = (char)stringReader.Read();
if (readChar == '\n' || (readChar == '\r' && stringReader.Peek() == '\n'))
{
// If it's a \r\n combo consume the \n part and throw it away.
if (readChar == '\r')
{
stringReader.Read();
}
if (inQoutedString)
{
if (readChar == '\r')
{
fieldBuilder.Append('\r');
}
fieldBuilder.Append('\n');
}
else
{
record.Add(fieldBuilder.ToString().TrimEnd());
fieldBuilder = new StringBuilder();
records.Add(record);
record = new List<string>();
inQoutedString = false;
}
}
else if (fieldBuilder.Length == 0 && !inQoutedString)
{
if (char.IsWhiteSpace(readChar))
{
// Ignore leading whitespace
}
else if (readChar == '"')
{
inQoutedString = true;
}
else if (readChar == ',')
{
record.Add(fieldBuilder.ToString().TrimEnd());
fieldBuilder = new StringBuilder();
}
else
{
fieldBuilder.Append(readChar);
}
}
else if (readChar == ',')
{
if (inQoutedString)
{
fieldBuilder.Append(',');
}
else
{
record.Add(fieldBuilder.ToString().TrimEnd());
fieldBuilder = new StringBuilder();
}
}
else if (readChar == '"')
{
if (inQoutedString)
{
if (stringReader.Peek() == '"')
{
stringReader.Read();
fieldBuilder.Append('"');
}
else
{
inQoutedString = false;
}
}
else
{
fieldBuilder.Append(readChar);
}
}
else
{
fieldBuilder.Append(readChar);
}
}
record.Add(fieldBuilder.ToString().TrimEnd());
records.Add(record);
return records;
}
Обратите внимание, что это не обрабатывает крайний случай полей, не разделенных двойными кавычками, но meerley имеет строку в кавычках внутри него. Смотрите этот пост для немного лучшего расширения, а также некоторые ссылки на некоторые правильные библиотеки.
Мне было скучно, поэтому я изменил некоторые вещи, которые написал. Он пытается инкапсулировать синтаксический анализ в OO манере, сокращая количество итераций через файл, он повторяется только один раз в верхней части foreach.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// usage:
// note this wont run as getting streams is not Implemented
// but will get you started
CSVFileParser fileParser = new CSVFileParser();
// TO Do: configure fileparser
PersonParser personParser = new PersonParser(fileParser);
List<Person> persons = new List<Person>();
// if the file is large and there is a good way to limit
// without having to reparse the whole file you can use a
// linq query if you desire
foreach (Person person in personParser.GetPersons())
{
persons.Add(person);
}
// now we have a list of Person objects
}
}
public abstract class CSVParser
{
protected String[] deliniators = { "," };
protected internal IEnumerable<String[]> GetRecords()
{
Stream stream = GetStream();
StreamReader reader = new StreamReader(stream);
String[] aRecord;
while (!reader.EndOfStream)
{
aRecord = reader.ReadLine().Split(deliniators,
StringSplitOptions.None);
yield return aRecord;
}
}
protected abstract Stream GetStream();
}
public class CSVFileParser : CSVParser
{
// to do: add logic to get a stream from a file
protected override Stream GetStream()
{
throw new NotImplementedException();
}
}
public class CSVWebParser : CSVParser
{
// to do: add logic to get a stream from a web request
protected override Stream GetStream()
{
throw new NotImplementedException();
}
}
public class Person
{
public String Name { get; set; }
public String Address { get; set; }
public DateTime DOB { get; set; }
}
public class PersonParser
{
public PersonParser(CSVParser parser)
{
this.Parser = parser;
}
public CSVParser Parser { get; set; }
public IEnumerable<Person> GetPersons()
{
foreach (String[] record in this.Parser.GetRecords())
{
yield return new Person()
{
Name = record[0],
Address = record[1],
DOB = DateTime.Parse(record[2]),
};
}
}
}
}
Существует две статьи о CodeProject, которые предоставляют код для решения, одна из которых использует StreamReader , а другая импортирует данные CSV с помощью драйвера Microsoft Text .
Хороший простой способ сделать это-открыть файл и прочитать каждую строку в массиве, связанном списке, data-structure-of-your-choice. Однако будьте осторожны в обращении с первой строкой.
Это может быть над вашей головой, но, кажется, есть прямой способ получить к ним доступ, а также с помощью строки подключения .
Почему бы не попробовать использовать Python вместо C# или VB? Он имеет хороший модуль CSV к import, который делает всю тяжелую работу за вас.
Я должен был использовать парсер CSV в .NET для проекта этим летом и остановился на драйвере Microsoft Jet Text. Вы указываете папку с помощью строки подключения, а затем запрашиваете файл с помощью инструкции SQL Select. Вы можете указать сильные типы, используя файл schema.ini. Сначала я этого не делал, но потом я получал плохие результаты, когда тип данных не был сразу очевиден, например, IP числа или запись типа "XYQ 3.9 SP1".
Одно ограничение, с которым я столкнулся, заключается в том, что он не может обрабатывать имена столбцов выше 64 символов; он усекает. Это не должно было быть проблемой, за исключением того, что я имел дело с очень плохо разработанными входными данными. Он возвращает ADO.NET DataSet.
Это было лучшее решение, которое я нашел. Я бы остерегался сворачивать свой собственный парсер CSV, так как я, вероятно, пропустил бы некоторые из конечных случаев, и я не нашел никаких других бесплатных пакетов парсинга CSV для .NET.
EDIT: кроме того, в каждом каталоге может быть только один файл schema.ini, поэтому я динамически добавлял к нему, чтобы строго ввести необходимые столбцы. Он будет только строго вводить указанные столбцы и выводить для любого неопределенного поля. Я действительно оценил это, так как имел дело с импортом fluid 70+ column CSV и не хотел указывать каждый столбец, только те, которые плохо себя ведут.
Я набрал какой-то код. Результат в datagridviewer выглядел неплохо. Он анализирует одну строку текста на arraylist объектов.
enum quotestatus
{
none,
firstquote,
secondquote
}
public static System.Collections.ArrayList Parse(string line,string delimiter)
{
System.Collections.ArrayList ar = new System.Collections.ArrayList();
StringBuilder field = new StringBuilder();
quotestatus status = quotestatus.none;
foreach (char ch in line.ToCharArray())
{
string chOmsch = "char";
if (ch == Convert.ToChar(delimiter))
{
if (status== quotestatus.firstquote)
{
chOmsch = "char";
}
else
{
chOmsch = "delimiter";
}
}
if (ch == Convert.ToChar(34))
{
chOmsch = "quotes";
if (status == quotestatus.firstquote)
{
status = quotestatus.secondquote;
}
if (status == quotestatus.none )
{
status = quotestatus.firstquote;
}
}
switch (chOmsch)
{
case "char":
field.Append(ch);
break;
case "delimiter":
ar.Add(field.ToString());
field.Clear();
break;
case "quotes":
if (status==quotestatus.firstquote)
{
field.Clear();
}
if (status== quotestatus.secondquote)
{
status =quotestatus.none;
}
break;
}
}
if (field.Length != 0)
{
ar.Add(field.ToString());
}
return ar;
}
Если вы можете гарантировать, что в данных нет запятых, то самый простой способ, вероятно, будет использовать String.split .
Например:
String[] values = myString.Split(',');
myObject.StringField = values[0];
myObject.IntField = Int32.Parse(values[1]);
Там могут быть библиотеки, которые вы могли бы использовать, чтобы помочь, но это, вероятно, так просто, как вы можете получить. Просто убедитесь, что вы не можете иметь запятые в данных, в противном случае вам нужно будет разбирать их лучше.