CSV-fájl import .Net

szavazat
99

Tudom, hogy ez egy kezdő kérdés, de én keresek egy egyszerű megoldás - úgy tűnik, nem kell egy.

Mi a legjobb módja annak, hogy CSV-fájlt importál egy erősen típusos adatszerkezet? Ismét egyszerű = jobb.

A kérdést 05/08/2008 05:43
a forrás felhasználó
Más nyelveken...                            


12 válasz

szavazat
72

A Microsoft TextFieldParser stabil és követi az RFC 4180 CSV fájlokat. Ne tegye ki a Microsoft.VisualBasicnévtér; ez egy alap eleme a .NET Framework, csak adj egy hivatkozást a globális Microsoft.VisualBasicszerelvény.

Ha összeállítása Windows (szemben a fekete-fehér), és nem előre, hogy elemezni „megtört” (non-RFC-kompatibilis) CSV fájlokat, akkor ez lenne a kézenfekvő választás, mert ez ingyenes, korlátlan, stabil, és aktívan támogatta, amelyek nagy része nem mondható FileHelpers.

Lásd még: Hogyan: Olvasás vesszővel elválasztott szöveges fájlok Visual Basic egy VB kódot példa.

Válaszolt 01/04/2009 20:58
a forrás felhasználó

szavazat
48

Távozás FileHelpers Open Source Library .

Válaszolt 05/08/2008 05:47
a forrás felhasználó

szavazat
21

Használjon OLED kapcsolati.

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();
Válaszolt 05/11/2008 15:41
a forrás felhasználó

szavazat
12

Ha várható meglehetősen összetett forgatókönyvek CSV elemzés, nem is hiszem fel gördülő saját elemző . Van egy csomó kiváló eszközök kint, mint FileHelpers , sőt azok is a CodeProject .

A lényeg az, hogy ez egy meglehetősen gyakori probléma, és akkor lehet fogadni, hogy egy csomó szoftverfejlesztők már gondolt, és megoldotta ezt a problémát.

Válaszolt 17/08/2008 00:44
a forrás felhasználó

szavazat
9

Egyetértek @ NotMyself . FileHelpers jól kipróbált és kezel minden esetben él, hogy akkor végül is foglalkozni, ha csináld magad. Megnézzük, hogy mit jelent, és csak FileHelpers írni a saját, ha teljesen biztos, hogy vagy (1) akkor soha nem kell kezelni a szélső esetek FileHelpers csinál, vagy (2) szeretsz írni ezt a fajta dolog, és a megfelelő lehet boldog, amikor meg kell elemezni dolgokat, mint ez:

1, "Bill", "Smith", "biztos", "No Comment"

2. 'Drake,', 'O'Malley', "portás,

Hoppá, én nem jegyzett és én egy új sorban!

Válaszolt 17/08/2008 00:53
a forrás felhasználó

szavazat
9

Brian ad egy szép megoldás átalakítására, hogy egy erősen típusos gyűjtemény.

A legtöbb CSV elemzési módszerek adott nem veszi figyelembe menekülő mezők vagy néhány más finomságok CSV fájlokat (például vágás mezők). Itt a kód Én személyesen használják. Ez egy kicsit durva a szélek körül, és elég sok nem hibajelentést.

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

Megjegyzendő, hogy ez nem kezeli a szélén szántóföld esetében nem hogy határolva idézőjel, de meerley amelynek idézett karakterlánc belsejébe. Lásd ezt a bejegyzést egy kicsit jobban expanation valamint néhány linkeket, hogy néhány megfelelő könyvtárakban.

Válaszolt 08/08/2008 17:20
a forrás felhasználó

szavazat
6

Unatkoztam, így én módosított néhány dolgot írtam. Úgy próbálja a beágyazására az elemzés egy OO módon whle vágás le az összeget ismétlések révén a fájlt, csak megismétli az oldal tetején 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]),
                };
            }
        }
    }
}
Válaszolt 08/08/2008 10:39
a forrás felhasználó

szavazat
5

Két cikket CodeProject amelyek kódot a megoldást, amelyik használ StreamReader és az egyik, hogy importálja a CSV-adatokat a Microsoft Text-illesztőprogram .

Válaszolt 05/08/2008 06:24
a forrás felhasználó

szavazat
2

Egy jó egyszerű módja az, hogy nyissa meg a fájlt, és olvassa minden sor egy tömb, láncolt lista, adat-struktúra-of-your-választás. Legyen óvatos kezelése az első sorban mégis.

Ez lehet a feje fölött, de úgy tűnik, hogy közvetlen módon hozzáférni számukra is egy connection string .

Miért nem próbálja Python helyett C # vagy VB? Ez egy szép CSV import modul, amely a munka nehezét az Ön számára.

Válaszolt 05/08/2008 05:49
a forrás felhasználó

szavazat
1

Aztán beírtam egy kódot. Az eredmény a datagridviewer jól nézett ki. Elemzi egyetlen sornyi szöveget egy ArrayList tárgyak.

    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;
    }
Válaszolt 09/09/2011 11:02
a forrás felhasználó

szavazat
1

Volt, hogy egy CSV elemzőnek .NET projekt ezen a nyáron, és megállapodott a Microsoft Jet szöveg illesztőprogram. Meg kell adni egy mappát a connection string, majd a lekérdezés egy fájlt a SQL Select utasítás. Megadhatja erős típusok használatával schema.ini fájlt. Én nem ezt először, de aztán egyre rossz eredmények, ahol a típus volt az adatok nem azonnal nyilvánvaló, mint például az IP szám vagy egy ilyen bejegyzést: „XYQ 3.9 SP1”.

Az egyik korlát belefutottam, hogy nem tudja kezelni az oszlop nevek felett 64 karakter; azt levágja. Ez nem lehet probléma, csak én foglalkoztam nagyon rosszul tervezett bemenő adatokat. Ez visszaad egy ADO.NET DataSet.

Ez volt a legjobb megoldás, amit találtam. Lennék óvatos gördülő saját CSV értelmező, mert azt valószínűleg hiányzik néhány vége esetben és nem találtunk más ingyenes CSV értelmezési csomagok .NET odakint.

EDIT: Is, ott is csak egy schema.ini fájl egy könyvtár, úgyhogy dinamikusan hozzá csatolt határozottan írja be a kívánt oszlopokat. Csak akkor erősen-írja a oszlopokhoz, és az ezekből bármely meghatározatlan területen. Nagyon nagyra ezt, mint én foglalkozó importáló fluid 70+ oszlop CSV, és nem akarta megadni az egyes oszlopok, csak a nem megfelelően működő is.

Válaszolt 16/08/2008 23:15
a forrás felhasználó

szavazat
0

Ha garantálja, hogy nincsenek vesszők az adatok, akkor a legegyszerűbb módja valószínűleg használni String.split .

Például:

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

Lehetnek könyvtárak akkor használja, hogy segítsen, de ez valószínűleg olyan egyszerű, mint kaphat. Csak győződjön meg róla, hogy nem lehet vesszőt az adatokat, különben meg kell elemezni, hogy jobb.

Válaszolt 05/08/2008 06:02
a forrás felhasználó

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