Net CSV Dosya İthalat

oy
99

Bunun acemi bir soru farkındayım ama basit bir çözüm arıyorum - biri olmalı gibi görünüyor.

özellikle yazılan veri yapısına bir CSV dosyasını almak için en iyi yolu nedir? Yine basit = daha iyi.

Oluştur 05/08/2008 saat 05:43
kaynak kullanıcı
Diğer dillerde...                            


12 cevaplar

oy
72

Microsoft'un TextFieldParser istikrarlı ve aşağıdaki RFC 4180 CSV dosyaları için. Tarafından ertelendi olmayın Microsoft.VisualBasicad; .NET Framework standart bileşen var, sadece küresel bir başvuru eklemek Microsoft.VisualBasicmontaj.

Eğer (Mono aksine) Windows için topluyoruz ve "kırık" (non-RFC-uyumlu) CSV dosyalarını ayrıştırmak zorunda tahmin yoksa kararlı, serbest sınırsız olduğu gibi, o zaman bu, bariz bir seçim olacağını, ve aktif olan çoğu için FileHelpers söylenemez, destekledi.

Ayrıca bakınız: Visual Basic virgülle sınırlandırılmış metin dosyaları itibaren okuyun: Nasıl bir VB kod örneğin.

Cevap 01/04/2009 saat 20:58
kaynak kullanıcı

Cevap 05/08/2008 saat 05:47
kaynak kullanıcı

oy
21

Bir OleDB bağlantısı kullanın.

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();
Cevap 05/11/2008 saat 15:41
kaynak kullanıcı

oy
12

CSV ayrıştırma için oldukça karmaşık senaryoları bekliyorsanız, hatta kendi ayrıştırıcı haddeleme kadar sanmıyorum . Mükemmel pek çok araç gibi pek vardır FileHelpers veya hatta olanları CodeProject .

Nokta bu oldukça yaygın bir sorun olduğunu ve bahse olabilir olan bir çok yazılım geliştiricilerin zaten düşünmüş ve bu sorunu çözmüş.

Cevap 17/08/2008 saat 00:44
kaynak kullanıcı

oy
9

Ben @ katılıyorum NotMyself . FileHelpers iyice test edilmiştir ve en sonunda bunu kendiniz yaparsanız uğraşmak gerekecek kenar durumlarda her türlü işler. Ya (1) kenar durumlarda FileHelpers işlemek gerekir asla konusunda hiçbir şüpheniz varsa FileHelpers ve sadece kendi yazıyor ne bir göz atın yapar veya (2) Eğer bu tarz şeyleri yazmayı seviyorum ve gidiyor Eğer böyle şeyler ayrıştırmak zorunda memnun olun:

1 "Bill", "Smith", "Danışman", "No Comment"

2, 'Drake', 'O'Malley', "Kapıcı,

Eyvah, alıntılanan ve ben yeni bir satırda değilim ben!

Cevap 17/08/2008 saat 00:53
kaynak kullanıcı

oy
9

Brian kesinlikle yazılı koleksiyona dönüştürmek için güzel bir çözüm sunar.

Verilen CSV ayrıştırma yöntemlerinin çoğu hesap kaçan alanları ya da (kırparak alanları gibi) CSV dosyaları diğer inceliklerini bazı içine almazlar. İşte ben şahsen kullanmak koddur. Bu biraz kenarlarda kaba ve hemen hemen hiçbir hata raporlama vardır.

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

Bu çift tırnak tarafından sınırlandırılmaktadır olmamak alanların kenar olaya el vermediğini unutmayın, ama bunun içinde bir alıntı dize sahip meerley. Bkz Bu yayını daha iyi bunların açıklaması biraz yanı sıra bazı uygun kütüphanelere bazı bağlantılar.

Cevap 08/08/2008 saat 17:20
kaynak kullanıcı

oy
6

i yazdı bazı şeyler değiştirilmiş yüzden sıkıldım. Üst foreach seferde sadece yinelediğinden dosyası üzerinden tekrarlamalar miktarına aşağı kesim whle bir OO şekilde ayrıştırmayı kapsülleyen 's deneyin.

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]),
                };
            }
        }
    }
}
Cevap 08/08/2008 saat 10:39
kaynak kullanıcı

oy
5

Çözüm kullanır biri için kodu sağlar CodeProject iki madde var StreamReader ve bir CSV veri ithalat kullanarak Microsoft Metin sürücüsü .

Cevap 05/08/2008 saat 06:24
kaynak kullanıcı

oy
2

bunu yapmak için iyi bir basit bir yolu dosyasını açın ve her bir diziye hattı, bağlantılı liste, veri yapısı-of-your-seçim okumaktır. gerçi ilk hat kullanımı konusunda dikkatli olun.

Bu başınızın üzerinden olabilir, ama aynı zamanda bir kullanarak bunlara erişmek için doğrudan bir yol var gibi görünüyor olabilir bağlantı dizesi .

Neden Python yerine C # veya VB kullanarak denemiyorsunuz? Bu sizin için tüm ağır işleri ithalat için güzel CSV modülüne sahiptir.

Cevap 05/08/2008 saat 05:49
kaynak kullanıcı

oy
1

Bazı kodunda yazdınız. datagridviewer sonuç iyi görünüyordu. Bu nesnelerin bir ArrayList tek bir metin satırını ayrıştırır.

    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;
    }
Cevap 09/09/2011 saat 11:02
kaynak kullanıcı

oy
1

Bu yaz bir proje için .NET bir CSV ayrıştırıcı kullanmak zorunda kaldı ve Microsoft Jet Metin Sürücü yerleşti. Daha sonra SQL Select deyimi kullanarak bir dosyayı sorgulamak, bir bağlantı dizesi kullanarak bir klasör belirtin. Bir schema.ini dosyasını kullanarak güçlü türleri belirtebilirsiniz. İlk başta bu yapmadım, ama sonra bu IP numaraları veya "XYQ 3.9 SP1" gibi bir giriş olarak verilerin türü hemen belli değildi kötü sonuçlar, başlamıştı.

Ben koştum bir sınırlaması, 64 karakter yukarıdaki sütun adları işleyemez ki; o keser. Çok kötü tasarlanmış veri girişi ile ilgili haricinde bu, bir sorun olmamalı. Bu bir ADO.NET DataSet döndürür.

Bu buldum iyi çözüm oldu. Muhtemelen son vakaların bazıları kaçırmak olacağından benim kendi CSV ayrıştırıcı haddeleme dikkatli olurdu ve ben orada .NET için herhangi bir başka serbest CSV ayrıştırma paketleri bulamadık.

DÜZENLEME: Ayrıca, yalnızca dizinde başına bir schema.ini dosyası olabilir, bu yüzden dinamik şiddetle ihtiyaç duyulan sütunları yazmak için kendisine eklenmiş. Bu sadece belirtilen sütunlar kuvvetle-yazın ve herhangi belirtilmemiş alan için anlaması olacaktır. Ben bir sıvı 70+ kolon CSV ithal ettiği ve her sütun, sadece hatalı çalışan olanları belirtmek istemedim gibi ben gerçekten bu takdir.

Cevap 16/08/2008 saat 23:15
kaynak kullanıcı

oy
0

Eğer verilerde hiçbir virgül olduğunu garanti ederseniz, o zaman en basit yolu muhtemelen kullanmak olacaktır String.split .

Örneğin:

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

Orada yardım etmek kullanabilirsiniz kütüphaneler olabilir, ama bu muhtemelen alabilirsiniz kadar basit olabilir. Sadece aksi takdirde daha iyi ayrıştırmak gerekir, veri virgül olamaz emin olun.

Cevap 05/08/2008 saat 06:02
kaynak kullanıcı

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