CSV souborů Dovoz NET

hlasů
99

Uvědomil jsem si, je to nováček otázka, ale já jsem hledal jednoduché řešení - Vypadá to, že by měl být jeden.

Jaký je nejlepší způsob, jak importovat soubor ve formátu CSV do silnými datové struktury? Opět jednoduché = lépe.

Položena 05/08/2008 v 05:43
zdroj uživatelem
V jiných jazycích...                            


12 odpovědí

hlasů
72

Microsoft TextFieldParser je stabilní a následuje RFC 4180 pro CSV souborů. Nenechte se odradit Microsoft.VisualBasicnázvů; to je standardní součástí .NET Framework, stačí přidat odkaz na světovém Microsoft.VisualBasicshromáždění.

Pokud kompilace pro Windows (na rozdíl od Mono) a nepředpokládám museli rozebrat „zlomené“ CSV souborů (non-RFC), pak by to bylo jasnou volbou, protože je to zdarma, neomezený, stabilní, a aktivně podporovány, většina z nich nelze říci pro FileHelpers.

Viz také: Jak na to: čtení ze souboru text oddělený čárkami v jazyka například do VB kódu.

Odpovězeno 01/04/2009 v 20:58
zdroj uživatelem

hlasů
48

Podívejte se na FileHelpers open source knihovnu .

Odpovězeno 05/08/2008 v 05:47
zdroj uživatelem

hlasů
21

Použít připojení 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();
Odpovězeno 05/11/2008 v 15:41
zdroj uživatelem

hlasů
12

Pokud jste očekával poměrně složité scénáře CSV analýze, ani vymyslet kolejových vlastní parser . Existuje mnoho vynikajících nástrojů tam, jako FileHelpers , nebo dokonce i ty z CodeProject .

Jde o to, to je poměrně častým problémem a ty by mohly vsadit, že mnoho softwarových vývojářů již přemýšlel a tento problém vyřešil.

Odpovězeno 17/08/2008 v 00:44
zdroj uživatelem

hlasů
9

Souhlasím s @ NotMyself . FileHelpers je dobře vyzkoušené a zpracovává všechny druhy případů hrany, které budete nakonec muset zabývat, pokud si to sami. Podívejte se na to, co dělá FileHelpers a psát pouze svůj vlastní, pokud si nejste absolutně jisti, že buď (1), nebudete muset zvládnout případů okrajové FileHelpers dělá, nebo (2) máte rádi psát tento druh věcí a jdou do být bez sebe radostí, když budete muset analyzovat věci, jako je toto:

1, "Bill", "Smith", "Supervisor", "No Comment"

2 'Drake,', 'O'Malley', "Janitor,

Jejda, já ne citoval a jsem na nový řádek!

Odpovězeno 17/08/2008 v 00:53
zdroj uživatelem

hlasů
9

Brian dává pěkný řešení pro převod na silně zadané kolekci.

Většina rozebrat metody CSV uvedené neberou v úvahu úniku polí nebo některé z dalších jemností CSV souborů (jako je ořezávání polí). Zde je kód, který jsem osobně používám. Je to trochu drsné kolem hran a nemá skoro žádnou zasílání zpráv o chybách.

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;
}

Všimněte si, že tento nezpracovává případ okraje polí není deliminated pomocí uvozovek, ale meerley má řetězec v uvozovkách uvnitř ní. Viz tento příspěvek pro trochu lepší expanation stejně jako některé odkazy na některé správných knihoven.

Odpovězeno 08/08/2008 v 17:20
zdroj uživatelem

hlasů
6

Byl jsem nudil, tak jsem upravený nějaké věci jsem napsal. To se snaží doporučovat to zapouzdřit parsování v OO způsobem whle kácení na množství iterací prostřednictvím souboru, pouze opakuje jednou nahoře 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]),
                };
            }
        }
    }
}
Odpovězeno 08/08/2008 v 10:39
zdroj uživatelem

hlasů
5

Existují dva články o CodeProject které poskytují kód pro roztok, ten, který používá StreamReader a ten, který importuje CSV data pomocí Text Driver společnosti Microsoft .

Odpovězeno 05/08/2008 v 06:24
zdroj uživatelem

hlasů
2

Dobrým jednoduchý způsob, jak to udělat, je otevřít soubor a číst každý řádek do pole, spojový seznam, datové struktury-of-your-výběr. Dávejte pozor na manipulaci s první řádek ačkoli.

To může být nad hlavou, ale zdá se, že přímý způsob, jak je přístup i pomocí připojovacího řetězce .

Proč nezkusit Python místo C # nebo VB? Má pěkný CSV modul pro import, který dělá všechnu těžkou práci za vás.

Odpovězeno 05/08/2008 v 05:49
zdroj uživatelem

hlasů
1

Jsem napsal v nějakém kódu. Výsledek v datagridviewer vypadalo dobře. Analyzuje jeden řádek textu ArrayList objektů.

    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;
    }
Odpovězeno 09/09/2011 v 11:02
zdroj uživatelem

hlasů
1

Musel jsem použít CSV analyzátor .NET pro projekt letos v létě, a usadil se na text ovladač Microsoft Jet. Určíte složku pomocí připojovacího řetězce, potom dotaz soubor pomocí příkazu SELECT. Můžete určit silné typy pomocí Schema.ini soubor. Nechtěl jsem to na první, ale pak jsem se dostat špatné výsledky, pokud je typ dat nebylo na první pohled patrné, jako IP čísla nebo položky jako „XYQ 3.9 SP1“.

Jediným omezením jsem narazil je, že to nemůže zvládnout názvy sloupců nad 64 znaků; to zkrátí. To by neměl být problém, i když jsem se zabýval velmi špatně navržených vstupních dat. Vrátí ADO.NET DataSet.

To bylo to nejlepší řešení, které jsem našel. Chtěl bych mít na pozoru před válcováním vlastní CSV parser, protože bych asi nechat ujít některé z koncových případů, a já jsem nenašel žádné jiné rozebrat balíčky bez CSV NET venku.

EDIT: Také může existovat pouze jeden soubor Schema.ini na seznamu, tak jsem dynamicky připojeny k němu silně zadejte potřebné sloupce. Bude to jen silně typ sloupce specifikované, a odvodit pro jakýkoliv nespecifikovaný pole. Opravdu jsem ocenil to, jak jsem se zabývala importem tekutiny 70+ sloupce CSV a nechtěl specifikovat každý sloupec, pouze nechová ty.

Odpovězeno 16/08/2008 v 23:15
zdroj uživatelem

hlasů
0

Pokud můžete zaručit, že jsou v datech žádné čárky, pak je nejjednodušší způsob, jak by se pravděpodobně používat string.split .

Například:

String[] values = myString.Split(',');
myObject.StringField = values[0];
myObject.IntField = Int32.Parse(values[1]);

Tam mohou být knihovny, které můžete použít na pomoc, ale to je asi tak jednoduché, jak se můžete dostat. Jen ujistěte se, že nemůže mít čárky v datech, v opačném případě budete muset analyzovat lépe.

Odpovězeno 05/08/2008 v 06:02
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more