108 votes

Importer un fichier CSV vers une structure de données fortement typée en .Net

Quelle est la meilleure façon d'importer un fichier CSV dans une structure de données fortement typée ?

0 votes

0 votes

Il s'agit d'un duplicata de stackoverflow.com/questions/1103495/

7 votes

Étant donné que cette question a été créée un an plus tôt que la 1103495, je pense que cette question est un doublon de celle-ci.

78voto

MarkJ Points 21438

Microsoft TextFieldParser est stable et suit RFC 4180 pour les fichiers CSV. Ne vous laissez pas décourager par le Microsoft.VisualBasic Il s'agit d'un composant standard dans le .NET Framework. Il suffit d'ajouter une référence à l'espace de noms global de l'entreprise. Microsoft.VisualBasic montage.

Si vous compilez pour Windows (par opposition à Mono) et ne prévoyez pas d'avoir à analyser des fichiers CSV "cassés" (non conformes au RFC), alors ce serait le choix évident, car il est gratuit, sans restriction, stable et activement supporté, ce qui n'est pas le cas de FileHelpers.

Voir aussi : Comment faire : Lire des fichiers texte délimités par des virgules en Visual Basic pour un exemple de code VB.

3 votes

Il n'y a en fait rien de spécifique à VB dans cette classe, si ce n'est son espace de noms mal nommé. Je choisirais définitivement cette bibliothèque si je n'avais besoin que d'un "simple" parseur CSV, parce qu'il n'y a rien à télécharger, à distribuer, ou à s'inquiéter en général. C'est pourquoi j'ai supprimé la formulation axée sur VB de cette réponse.

0 votes

@Aaronaught Je pense que vos modifications sont surtout une amélioration. Bien que cette RFC ne fasse pas nécessairement autorité, car de nombreux auteurs de CSV ne s'y conforment pas, par exemple Excel. n'utilise pas toujours une virgule dans des fichiers "CSV". De plus, ma réponse précédente ne disait-elle pas déjà que la classe pouvait être utilisée à partir de C# ?

0 votes

El TextFieldParser fonctionnera également pour les fichiers délimités par des tabulations et d'autres fichiers générés par Excel. Je me rends compte que votre réponse précédente ne prétendait pas que la bibliothèque était spécifique à VB, mais elle m'a semblé impliquer qu'elle l'était vraiment signifiait pour VB, et non prévu pour être utilisé à partir de C#, ce qui ne me semble pas être le cas - il y a des classes vraiment utiles dans MSVB.

51voto

NotMyself Points 7567

Vérifiez FileHelpers .

22voto

Kevin Points 2548

Utilisez une connexion 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();

0 votes

Cela nécessite un accès au système de fichiers. Pour autant que je sache, il n'existe aucun moyen de faire fonctionner OLEDB avec des flux en mémoire :(

3 votes

@UserControl, bien sûr, il faut un accès au système de fichiers. Il a posé une question sur l'importation d'un fichier CSV

1 votes

Je ne me plains pas. En fait, je préférerais la solution OLEDB au reste, mais j'ai été frustré tant de fois quand j'ai eu besoin d'analyser des CSV dans des applications ASP.NET que j'ai voulu le noter.

13voto

Jon Limjap Points 46429

Si vous vous attendez à des scénarios assez complexes pour l'analyse CSV, ne pense même pas à mettre en place notre propre analyseur syntaxique. . Il existe un grand nombre d'excellents outils, tels que FileHelpers ou même ceux de CodeProject .

Le fait est qu'il s'agit d'un problème assez courant et vous pouvez parier que beaucoup de développeurs de logiciels ont déjà réfléchi à ce problème et l'ont résolu.

0 votes

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien à titre de référence. Les réponses ne comportant qu'un lien peuvent devenir invalides si la page liée change. - De la revue

0 votes

Merci @techspider J'espère que vous avez noté que ce post date de la période bêta de StackOverflow :D Cela étant dit, de nos jours, les outils CSV sont mieux fournis par les paquets Nuget - donc je ne suis pas sûr que même les réponses aux liens soient à l'abri des cycles d'évolution technologique vieux de 8 ans.

9voto

ICR Points 6960

Brian propose une solution intéressante pour la convertir en une collection fortement typée.

La plupart des méthodes d'analyse CSV proposées ne tiennent pas compte de l'échappement des champs ou de certaines autres subtilités des fichiers CSV (comme le découpage des champs). Voici le code que j'utilise personnellement. Il est un peu brut de décoffrage et n'a pratiquement aucun rapport d'erreur.

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

Notez que cela ne gère pas le cas limite des champs qui ne sont pas délimités par des guillemets doubles, mais qui contiennent simplement une chaîne entre guillemets. Voir ce poste pour une meilleure explication ainsi que des liens vers de bonnes bibliothèques.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X