J'aimerais créer un tableau à partir d'un fichier CSV.
C'est à peu près aussi simple que vous pouvez l'imaginer, le fichier CSV n'aura jamais qu'une seule ligne et ces valeurs:
Device, SignalStrength, Location, Time, Age.
Je voudrais mettre ces valeurs dans un tableau à une dimension.
J'ai essayé quelques exemples, mais ils ont tous été plus compliqués que nécessaire.
S'il n'y a qu'une seule ligne, faites quelque chose comme ceci:
using System;
using System.IO;
class Program
{
static void Main()
{
String[] values = File.ReadAllText(@"d:\test.csv").Split(',');
}
}
Vous pouvez essayer quelque chose comme l'extrait LINQ ci-dessous.
string[] allLines = File.ReadAllLines(@"E:\Temp\data.csv");
var query = from line in allLines
let data = line.Split(',')
select new
{
Device = data[0],
SignalStrength = data[1],
Location = data[2],
Time = data[3],
Age = Convert.ToInt16(data[4])
};
UPDATE: Au fil du temps, les choses ont évolué. À partir de maintenant, je préférerais utiliser cette bibliothèque http://www.aspnetperformance.com/post/LINQ-to-CSV-library.aspx
Voici une fonction simple que j'ai faite. Il accepte une chaîne de caractères CSV et renvoie un tableau de champs:
Cela fonctionne bien avec les fichiers CSV générés par Excel et de nombreuses autres variantes.
public static string[] ParseCsvRow(string r)
{
string[] c;
string t;
List<string> resp = new List<string>();
bool cont = false;
string cs = "";
c = r.Split(new char[] { ',' }, StringSplitOptions.None);
foreach (string y in c)
{
string x = y;
if (cont)
{
// End of field
if (x.EndsWith("\""))
{
cs += "," + x.Substring(0, x.Length - 1);
resp.Add(cs);
cs = "";
cont = false;
continue;
}
else
{
// Field still not ended
cs += "," + x;
continue;
}
}
// Fully encapsulated with no comma within
if (x.StartsWith("\"") && x.EndsWith("\""))
{
if ((x.EndsWith("\"\"") && !x.EndsWith("\"\"\"")) && x != "\"\"")
{
cont = true;
cs = x;
continue;
}
resp.Add(x.Substring(1, x.Length - 2));
continue;
}
// Start of encapsulation but comma has split it into at least next field
if (x.StartsWith("\"") && !x.EndsWith("\""))
{
cont = true;
cs += x.Substring(1);
continue;
}
// Non encapsulated complete field
resp.Add(x);
}
return resp.ToArray();
}
Cette version corrigée du code ci-dessus rappelle le dernier élément de la ligne CVS ;-)
(testé avec un fichier CSV avec 5400 lignes et 26 éléments par ligne)
public static string[] CSVRowToStringArray(string r, char fieldSep = ',', char stringSep = '\"') {
bool bolQuote = false;
StringBuilder bld = new StringBuilder();
List<string> retAry = new List<string>();
foreach (char c in r.ToCharArray())
if ((c == fieldSep && !bolQuote))
{
retAry.Add(bld.ToString());
bld.Clear();
}
else
if (c == stringSep)
bolQuote = !bolQuote;
else
bld.Append(c);
/* to solve the last element problem */
retAry.Add(bld.ToString()); /* added this line */
return retAry.ToArray();
}
C’est ce que j’ai utilisé dans un projet: analyser une seule ligne de données.
private string[] csvParser(string csv, char separator = ',')
{
List <string> = new <string>();
string[] temp = csv.Split(separator);
int counter = 0;
string data = string.Empty;
while (counter < temp.Length)
{
data = temp[counter].Trim();
if (data.Trim().StartsWith("\""))
{
bool isLast = false;
while (!isLast && counter < temp.Length)
{
data += separator.ToString() + temp[counter + 1];
counter++;
isLast = (temp[counter].Trim().EndsWith("\""));
}
}
parsed.Add(data);
counter++;
}
return parsed.ToArray();
}
http://zamirsblog.blogspot.com/2013/09/c-csv-parser-csvparser.html
Ma solution gère les guillemets, les séparateurs de champs et de chaînes, etc. Elle est courte et agréable.
public static string[] CSVRowToStringArray(string r, char fieldSep = ',', char stringSep = '\"')
{
bool bolQuote = false;
StringBuilder bld = new StringBuilder();
List<string> retAry = new List<string>();
foreach (char c in r.ToCharArray())
if ((c == fieldSep && !bolQuote))
{
retAry.Add(bld.ToString());
bld.Clear();
}
else
if (c == stringSep)
bolQuote = !bolQuote;
else
bld.Append(c);
return retAry.ToArray();
}
Tout d'abord besoin de comprendre ce qu'est le CSV et comment l'écrire.
(La plupart des réponses (toutes pour le moment) n'utilisent pas cette exigence, c'est pourquoi elles sont toutes fausses!)
/r/n
) est la rangée "table" suivante.\t
ou ,
./r/n
symboles à l'intérieur de la cellule (la cellule doit commencer par le symbole de guillemets doubles et avoir à la fin un guillemet double à la fin)Il y a quelque temps, j'avais écrit un cours simple pour la lecture/écriture au format CSV basé sur la norme Microsoft.VisualBasic.FileIO
bibliothèque. En utilisant cette classe simple, vous pourrez travailler avec CSV comme avec un tableau à 2 dimensions.
Exemple simple d'utilisation de ma bibliothèque:
Csv csv = new Csv("\t");//delimiter symbol
csv.FileOpen("c:\\file1.csv");
var row1Cell6Value = csv.Rows[0][5];
csv.AddRow("asdf","asdffffff","5")
csv.FileSave("c:\\file2.csv");
Vous pouvez trouver ma classe grâce au lien suivant et étudier comment elle est écrite: https://github.com/ukushu/DataExporter
Ce code de bibliothèque est très rapide au travail et le code source est très court.
PS: Dans le même temps, cette solution ne fonctionnera pas pour l'unité.
PS2: Une autre solution consiste à utiliser la bibliothèque "LINQ-to-CSV". Cela doit aussi bien fonctionner. Mais ce sera plus gros.