¿Alguien sabe de una biblioteca de código abierto que le permite analizar y leer los archivos .csv
en C#?Lectura de archivos CSV en C#
Respuesta
Eche un vistazo a A Fast CSV Reader en CodeProject.
Sí, ese es genial, también conocido como LumenWorks.Framework.IO.Csv por Sebastien Lorien – codeulike
Aquí, escrito por los tuyos para utilizar colecciones genéricas y bloques de iteradores. Es compatible con campos de texto adjuntos de comillas dobles (incluidos los que abarcan varias líneas) utilizando la convención de doble escape (por lo que ""
dentro de un campo entre comillas se lee como carácter de comillas simples). No es compatible con:
- comilla simple texto encerrado
- \ -escape al texto de la cita
- delimitadores alternativos (sin embargo, no va a funcionar en el tubo o campos delimitados por tabuladores)
- campos de texto que comienzan Unquoted con una cotización
Pero todas ellas serían lo suficientemente fáciles de agregar si las necesita. No lo he comparado en ninguna parte (me gustaría ver algunos resultados), pero el rendimiento debería ser muy bueno - mejor que cualquier otro que sea .Split()
basado de todos modos.
actualización: se sentía como la adición de soporte texto entre comilla simple. Es un cambio simple, pero lo escribí directamente en la ventana de respuesta para que no haya sido probado. Use el enlace de revisión en la parte inferior si prefiere el código anterior (probado).
public static class CSV
{
public static IEnumerable<IList<string>> FromFile(string fileName)
{
foreach (IList<string> item in FromFile(fileName, ignoreFirstLineDefault)) yield return item;
}
public static IEnumerable<IList<string>> FromFile(string fileName, bool ignoreFirstLine)
{
using (StreamReader rdr = new StreamReader(fileName))
{
foreach(IList<string> item in FromReader(rdr, ignoreFirstLine)) yield return item;
}
}
public static IEnumerable<IList<string>> FromStream(Stream csv)
{
foreach (IList<string> item in FromStream(csv, ignoreFirstLineDefault)) yield return item;
}
public static IEnumerable<IList<string>> FromStream(Stream csv, bool ignoreFirstLine)
{
using (var rdr = new StreamReader(csv))
{
foreach (IList<string> item in FromReader(rdr, ignoreFirstLine)) yield return item;
}
}
public static IEnumerable<IList<string>> FromReader(TextReader csv)
{
//Probably should have used TextReader instead of StreamReader
foreach (IList<string> item in FromReader(csv, ignoreFirstLineDefault)) yield return item;
}
public static IEnumerable<IList<string>> FromReader(TextReader csv, bool ignoreFirstLine)
{
if (ignoreFirstLine) csv.ReadLine();
IList<string> result = new List<string>();
StringBuilder curValue = new StringBuilder();
char c;
c = (char)csv.Read();
while (csv.Peek() != -1)
{
switch (c)
{
case ',': //empty field
result.Add("");
c = (char)csv.Read();
break;
case '"': //qualified text
case '\'':
char q = c;
c = (char)csv.Read();
bool inQuotes = true;
while (inQuotes && csv.Peek() != -1)
{
if (c == q)
{
c = (char)csv.Read();
if (c != q)
inQuotes = false;
}
if (inQuotes)
{
curValue.Append(c);
c = (char)csv.Read();
}
}
result.Add(curValue.ToString());
curValue = new StringBuilder();
if (c == ',') c = (char)csv.Read(); // either ',', newline, or endofstream
break;
case '\n': //end of the record
case '\r':
//potential bug here depending on what your line breaks look like
if (result.Count > 0) // don't return empty records
{
yield return result;
result = new List<string>();
}
c = (char)csv.Read();
break;
default: //normal unqualified text
while (c != ',' && c != '\r' && c != '\n' && csv.Peek() != -1)
{
curValue.Append(c);
c = (char)csv.Read();
}
result.Add(curValue.ToString());
curValue = new StringBuilder();
if (c == ',') c = (char)csv.Read(); //either ',', newline, or endofstream
break;
}
}
if (curValue.Length > 0) //potential bug: I don't want to skip on a empty column in the last record if a caller really expects it to be there
result.Add(curValue.ToString());
if (result.Count > 0)
yield return result;
}
private static bool ignoreFirstLineDefault = false;
}
¿Puede manejar comas dentro de la secuencia entrecomillada? "me gusta, esto" ... ¿y puede manejar los retornos de carro en cadenas entrecomilladas? ... esas son algunas de las cosas que tienden a causar problemas ... – codeulike
Sí, puede manejar ambos. Ese es el punto de las cadenas entre comillas. –
Todavía me gusta esto, pero si tuviera que hacerlo probablemente heredaría TextReader –
Me gusta mucho la biblioteca FileHelpers. Es rápido, es C# 100%, está disponible para GRATIS, es muy flexible y fácil de usar.
El asistente de FileHelpers parece realmente útil para crear clases estándar rápidamente. –
El last time this question was asked, aquí está the answer di:
Si sólo está tratando de leer un archivo CSV con C#, lo más fácil es utilizar la clase Microsoft.VisualBasic.FileIO.TextFieldParser. En realidad está integrado en .NET Framework, en lugar de ser una extensión de terceros.
Sí, está en Microsoft.VisualBasic.dll
, pero eso no significa que no pueda usarlo desde C# (o cualquier otro lenguaje CLR).
Aquí hay un ejemplo de uso, tomada de la MSDN documentation:
Using MyReader As New _
Microsoft.VisualBasic.FileIO.TextFieldParser("C:\testfile.txt")
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
Dim currentField As String
For Each currentField In currentRow
MsgBox(currentField)
Next
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & _
"is not valid and will be skipped.")
End Try
End While
End Using
Una vez más, este ejemplo es en VB.NET, pero sería trivial para traducirlo a C#.
+1 No sabía de esta clase pero funciona muy bien. –
He usado esta clase varias veces y la recomendaría. Integrarse en .NET significa que no tiene que preocuparse por los problemas de licencia/distribución. –
Además del análisis/lectura, algunas bibliotecas hacen otras cosas agradables como convertir los datos analizados en objetos para usted.
Aquí hay un ejemplo del uso de CsvHelper (una biblioteca que mantengo) para leer un archivo CSV en objetos.
var csv = new CsvHelper(File.OpenRead("file.csv"));
var myCustomObjectList = csv.Reader.GetRecords<MyCustomObject>();
De manera predeterminada, las convenciones se utilizan para hacer coincidir los encabezados/columnas con las propiedades.Puede cambiar el comportamiento cambiando la configuración.
// Using attributes:
public class MyCustomObject
{
[CsvField(Name = "First Name")]
public string StringProperty { get; set; }
[CsvField(Index = 0)]
public int IntProperty { get; set; }
[CsvField(Ignore = true)]
public string ShouldIgnore { get; set; }
}
A veces no "posee" el objeto con el que desea rellenar los datos. En este caso, puede usar un mapeo de clase fluido.
// Fluent class mapping:
public sealed class MyCustomObjectMap : CsvClassMap<MyCustomObject>
{
public MyCustomObjectMap()
{
Map(m => m.StringProperty).Name("First Name");
Map(m => m.IntProperty).Index(0);
Map(m => m.ShouldIgnore).Ignore();
}
}
Lo que no entiendo de la documentación es, ¿cuándo uso el mapeo y cuándo no debería usar el mapeo? Digamos que solo quiero analizar un archivo xml y palabras clave adicionales y sus datos adjuntos. ¿Necesito usar un mapa para eso? –
Si está analizando XML, no debe usar una biblioteca CSV para hacerlo. La asignación de atributos ya no existe desde 2.0. La razón por la que usaría un archivo de asignación es si desea cambiar alguna de las formas predeterminadas en que la biblioteca lee el archivo. Una asignación le dará mucho control sobre cómo se lee/escribe el archivo. –
Opps, eso fue un error ... Quise decir * CSV por supuesto. El mapeo no existe en .NET 4.0/5? Además, en esa nota, ¿qué recomendaría que use en su lugar para analizar CSV y tomar solo ciertas palabras clave y sus datos? –
Estoy implementando la respuesta de Daniel Pryden en C#, por lo que es más fácil de cortar y pegar y personalizar. Creo que este es el método más fácil para analizar archivos CSV. Solo agrega una referencia y básicamente has terminado.
Añadir la Microsoft.VisualBasic
referencia a su proyecto
Entonces aquí es código de ejemplo en C# de la respuesta de Joel:
using (Microsoft.VisualBasic.FileIO.TextFieldParser MyReader = new
Microsoft.VisualBasic.FileIO.TextFieldParser(filename))
{
MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
MyReader.SetDelimiters(",");
while (!MyReader.EndOfData)
{
try
{
string[] fields = MyReader.ReadFields();
if (first)
{
first = false;
continue;
}
// This is how I treat my data, you'll need to throw this out.
//"Type" "Post Date" "Description" "Amount"
LineItem li = new LineItem();
li.date = DateTime.Parse(fields[1]);
li.description = fields[2];
li.Value = Convert.ToDecimal(fields[3]);
lineitems1.Add(li);
}
catch (Microsoft.VisualBasic.FileIO.MalformedLineException ex)
{
MessageBox.Show("Line " + ex.Message +
" is not valid and will be skipped.");
}
}
}
Puede utilizar Microsoft.VisualBasic.FileIO.TextFieldParser
get ejemplo de código siguiente del artículo anterior
static void Main()
{
string [email protected]"C:\Users\Administrator\Desktop\test.csv";
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);
Console.WriteLine("Rows count:" + csvData.Rows.Count);
Console.ReadLine();
}
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
DataTable csvData = new DataTable();
try
{
using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
- 1. Lectura de archivos .csv en listas de Python
- 2. archivos CSV de lectura en donde numpy delimitador es ""
- 3. ¿Lectura de un archivo CSV en .NET?
- 4. lectura C archivos binarios
- 5. Lectura del archivo .csv en php
- 6. Lectura de archivos delimitados en C++
- 7. lectura/escritura de archivos bmp en c
- 8. Lectura programática de archivos PDF en C#
- 9. lectura de un archivo CSV en MATLAB
- 10. ¿Lectura repetida de CSV en Python?
- 11. Lectura en archivos XML/KML con C#
- 12. Java: archivo CSV de lectura y escritura
- 13. Lectura de datos CSV de un archivo
- 14. C# TextWriter, permite la lectura de archivos:
- 15. de lectura y escritura en el mismo archivo csv
- 16. líneas de lectura de dos archivos en un bucle while
- 17. Lectura de archivos XML incrustados C#
- 18. Lectura de csv con fecha y hora
- 19. cabezales de lectura del analizador csv
- 20. Lectura de archivos MP3
- 21. Lectura de archivos .DXF
- 22. read.csv es extremadamente lento en la lectura de archivos csv con un gran número de columnas
- 23. lectura en archivos CSV menor que 10K de S3 con Ruby 1.9.2 p290
- 24. Lectura de gml en C#
- 25. Python3: escribiendo archivos csv
- 26. Combinando 2 archivos CSV
- 27. Lectura de PDF en C#
- 28. Lectura de archivos XML en C# con XpathNavigator
- 29. Lectura de archivos .msg
- 30. Lectura de archivos MIDI
¡Encontré uno! http://www.filehelpers.com/ :) – diegocaro