CSV Εισαγωγή αρχείου σε .Net

ψήφοι
99

Αντιλαμβάνομαι αυτό είναι ένα newbie ερώτηση, αλλά ψάχνω για μια απλή λύση - φαίνεται ότι θα πρέπει να υπάρχει ένα.

Ποιος είναι ο καλύτερος τρόπος για να εισαγάγετε ένα αρχείο CSV σε ένα έντονα-δακτυλογραφημένο δομή δεδομένων; Και πάλι απλά = καλύτερα.

Δημοσιεύθηκε 05/08/2008 στις 05:43
πηγή χρήστη
Σε άλλες γλώσσες...                            


12 απαντήσεις

ψήφοι
72

Της Microsoft TextFieldParser είναι σταθερή και ακολουθεί το RFC 4180 για τα αρχεία CSV. Μην αποθαρρύνεστε από το Microsoft.VisualBasicχώρο ονομάτων? είναι ένα πρότυπο στοιχείο στο .NET Framework, απλά προσθέστε μια αναφορά για την παγκόσμια Microsoft.VisualBasicσυνέλευση.

Αν κατάρτιση για τα Windows (σε αντίθεση με Mono) και δεν προβλέπουν να χρειάζεται να αναλύσει «σπασμένα» τα αρχεία CSV (μη-RFC-συμβατό), τότε αυτό θα ήταν η προφανής επιλογή, καθώς είναι δωρεάν, απεριόριστη, σταθερή, και ενεργά υποστήριξε, οι περισσότερες από τις οποίες δεν μπορεί να ειπωθεί για FileHelpers.

Δείτε επίσης: Πώς να: Διαβάστε Από τα αρχεία κειμένου οριοθετημένου με κόμματα σε Visual Basic για έναν κώδικα VB παράδειγμα.

Απαντήθηκε 01/04/2009 στις 20:58
πηγή χρήστη

ψήφοι
48

Ελέγξτε FileHelpers Open Source βιβλιοθήκη .

Απαντήθηκε 05/08/2008 στις 05:47
πηγή χρήστη

ψήφοι
21

Χρησιμοποιήστε μια σύνδεση 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();
Απαντήθηκε 05/11/2008 στις 15:41
πηγή χρήστη

ψήφοι
12

Αν περιμένετε αρκετά σύνθετα σενάρια για CSV ανάλυσης, δεν σκέφτονται ακόμη και από το τροχαίο το δικό μας πρόγραμμα ανάλυσης . Υπάρχουν πολλά εξαιρετικά εργαλεία εκεί έξω, όπως FileHelpers , ή ακόμα και αυτοί από CodeProject .

Το σημείο είναι αυτό είναι ένα αρκετά κοινό πρόβλημα και θα μπορούσε να στοιχηματίσει ότι πολλοί από τους προγραμματιστές λογισμικού έχουν ήδη σκεφτεί και να λύσει αυτό το πρόβλημα.

Απαντήθηκε 17/08/2008 στις 00:44
πηγή χρήστη

ψήφοι
9

Συμφωνώ με @ NotMyself . FileHelpers είναι καλά δοκιμασμένο και χειρίζεται όλα τα είδη των περιπτώσεων ακμής που τελικά θα πρέπει να ασχοληθεί με αν το κάνετε μόνοι σας. Ρίξτε μια ματιά σε ό, τι FileHelpers κάνει και μόνο γράψετε τη δική σας, αν είστε απόλυτα σίγουροι ότι είτε (1) δε θα χρειαστεί ποτέ να χειριστεί τις υποθέσεις άκρη FileHelpers κάνει, ή (2) να σας αρέσει το γράψιμο αυτού του είδους τα πράγματα και θα είναι περιχαρής όταν έχετε να αναλύσει τα πράγματα όπως αυτό:

1, "Bill", "Smith", "Επόπτης", "Δεν Σχόλιο"

2, 'Drake', 'O'Malley', «επιστάτη,

Ωχ, δεν είμαι εισηγμένες και είμαι σε μια νέα γραμμή!

Απαντήθηκε 17/08/2008 στις 00:53
πηγή χρήστη

ψήφοι
9

Brian δίνει μια ωραία λύση για τη μετατροπή σε μια έντονα δακτυλογραφημένη συλλογή.

Οι περισσότερες από τις μεθόδους ανάλυσης 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 έχουν χρηματιστηριακή κορδόνι στο εσωτερικό του. Δείτε αυτό το post για ένα κομμάτι μιας καλύτερης expanation καθώς και μερικές συνδέσεις με ορισμένες κατάλληλες βιβλιοθήκες.

Απαντήθηκε 08/08/2008 στις 17:20
πηγή χρήστη

ψήφοι
6

Είχα βαρεθεί γι 'αυτό τροποποιημένο κάποια πράγματα έγραψα. Θα προσπαθήσουμε να ενσωματώσει το parsing σε ένα τρόπο OO whle μειώνοντας την ποσότητα των επαναλήψεων μέσα από το αρχείο, το μόνο επαναλαμβάνεται μία φορά στην κορυφή 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]),
                };
            }
        }
    }
}
Απαντήθηκε 08/08/2008 στις 10:39
πηγή χρήστη

ψήφοι
5

Υπάρχουν δύο άρθρα σχετικά με CodeProject που παρέχουν κώδικα για μια λύση, μια που χρησιμοποιεί StreamReader και ένα που εισάγει τα δεδομένα CSV χρησιμοποιώντας το πρόγραμμα οδήγησης κειμένου της Microsoft .

Απαντήθηκε 05/08/2008 στις 06:24
πηγή χρήστη

ψήφοι
2

Ένας καλός απλός τρόπος για να το κάνετε είναι να ανοίξετε το αρχείο και να διαβάσετε κάθε γραμμή σε έναν πίνακα, συνδεδεμένη λίστα, δομή δεδομένων του-σας-επιλογή. Να είστε προσεκτικοί σχετικά με το χειρισμό της πρώτης γραμμής, όμως.

Αυτό μπορεί να είναι πάνω από το κεφάλι σου, αλλά φαίνεται να είναι ένα άμεσο τρόπο για να έχουν πρόσβαση σε αυτά, καθώς και τη χρήση εκεί συμβολοσειρά σύνδεσης .

Γιατί να μην δοκιμάστε να χρησιμοποιήσετε την Python αντί για C # ή VB; Έχει μια ωραία ενότητα CSV για εισαγωγή που κάνει όλη τη βαριά ανύψωση για σας.

Απαντήθηκε 05/08/2008 στις 05:49
πηγή χρήστη

ψήφοι
1

Έχω πληκτρολογήσει κάποιο κωδικό. Το αποτέλεσμα της 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;
    }
Απαντήθηκε 09/09/2011 στις 11:02
πηγή χρήστη

ψήφοι
1

Έπρεπε να χρησιμοποιήσετε ένα πρόγραμμα ανάλυσης CSV σε .NET για ένα έργο το καλοκαίρι και εγκαταστάθηκαν στο πρόγραμμα οδήγησης κειμένου Microsoft Jet. Μπορείτε να καθορίσετε ένα φάκελο χρησιμοποιώντας μια σειρά σύνδεση, τότε το ερώτημα σε ένα αρχείο χρησιμοποιώντας μια SQL Επιλέξτε δήλωση. Μπορείτε να καθορίσετε ισχυρή τύπους χρησιμοποιώντας ένα αρχείο Schema.ini. Εγώ δεν το κάνετε αυτό στην αρχή, αλλά στη συνέχεια είχε πάρει άσχημα αποτελέσματα, όπου το είδος των δεδομένων δεν ήταν άμεσα εμφανής, όπως αριθμούς IP ή μια καταχώρηση σαν «XYQ 3.9 SP1».

Ένας περιορισμός έτρεξα σε είναι ότι δεν μπορεί να χειριστεί τα ονόματα των στηλών πάνω από 64 χαρακτήρες? περικόπτει. Αυτό δεν πρέπει να είναι ένα πρόβλημα, εκτός είχα να κάνω με πολύ κακώς σχεδιασμένη δεδομένα εισόδου. Επιστρέφει ένα DataSet ADO.NET.

Αυτή ήταν η καλύτερη λύση που βρήκα. Θα ήθελα να είναι δύσπιστοι όσον αφορά το τροχαίο το δικό μου πρόγραμμα ανάλυσης CSV, δεδομένου ότι θα χάσει κατά πάσα πιθανότητα κάποια από τα τέλη περιπτώσεις, και δεν βρήκα άλλα πακέτα ανάλυσης δωρεάν CSV για .NET εκεί έξω.

EDIT: Επίσης, μπορεί να υπάρχει μόνο ένα αρχείο Schema.ini ανά κατάλογο, οπότε δυναμικά προσαρτάται στο να πληκτρολογήσετε έντονα τις απαραίτητες στήλες. Θα μόνο έντονα, πληκτρολογήστε τις στήλες που ορίζονται, και συμπεράνουμε για κάθε απροσδιόριστο πεδίο. Πραγματικά εκτίμησα αυτό, όπως ήμουν ασχολούνται με την εισαγωγή ενός υγρού 70 + CSV στήλη και δεν ήθελε να αναφερθεί κάθε στήλη, μόνο αυτά που παρουσιάζει εσφαλμένη συμπεριφορά.

Απαντήθηκε 16/08/2008 στις 23:15
πηγή χρήστη

ψήφοι
0

Αν μπορεί να εγγυηθεί ότι δεν υπάρχουν κόμματα στα δεδομένα, τότε ο απλούστερος τρόπος θα μπορούσε πιθανότατα να είναι η χρήση String.split .

Για παράδειγμα:

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

Μπορεί να υπάρχουν βιβλιοθήκες θα μπορούσατε να χρησιμοποιήσετε για να βοηθήσει, αλλά αυτό είναι ίσως τόσο απλό όσο μπορείτε να πάρετε. Απλά βεβαιωθείτε ότι δεν μπορείτε να έχετε κόμμα στα δεδομένα, διαφορετικά θα πρέπει να αναλύσει καλύτερα.

Απαντήθηκε 05/08/2008 στις 06:02
πηγή χρήστη

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