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.
0 votes
Vérifiez Bibliothèque Open Source FileHelpers .
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.
2 votes
Merci, Matt. J'essayais juste de les relier entre elles, sans indiquer laquelle venait en premier. Vous verrez que j'ai exactement le même texte sur l'autre question qui pointe vers celle-ci. Y a-t-il une meilleure façon de lier deux questions ensemble ?
0 votes
Lire un fichier CSV en .NET ? est un duplicata ouvert de cette question