读取CSV文件并将值存储到数组中

时间:2021-03-27 13:33:03

I am trying to read a *.csv-file.

我正在读取一个*.csv文件。

The *.csv-file consist of two columns separated by semicolon (";").

*。csv-file由分号(“;”)分隔的两列组成。

I am able to read the *.csv-file using StreamReader and able to separate each line by using the Split() function. I want to store each column into a separate array and then display it.

我能读懂*。csv文件使用StreamReader,并且可以通过使用Split()函数来分离每一行。我想将每一列存储到一个单独的数组中,然后显示它。

Is it possible to do that?

有可能吗?

17 个解决方案

#1


278  

You can do it like this:

你可以这样做:

using System.IO;

static void Main(string[] args)
{
    using(var reader = new StreamReader(@"C:\test.csv"))
    {
        List<string> listA = new List<string>();
        List<string> listB = new List<string>();
        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            var values = line.Split(';');

            listA.Add(values[0]);
            listB.Add(values[1]);
        }
    }
}

#2


72  

My favourite csv parser is one built into .net library. This is a hidden treasure inside Microsoft.VisualBasic namespace. Below is a sample code:

我最喜欢的csv解析器是内建在。net库中的。这是微软内部隐藏的宝藏。VisualBasic名称空间。下面是一个示例代码:

using Microsoft.VisualBasic.FileIO;

var path = @"C:\Person.csv"; // Habeeb, "Dubai Media City, Dubai"
using (TextFieldParser csvParser = new TextFieldParser(path))
{
 csvParser.CommentTokens = new string[] { "#" };
 csvParser.SetDelimiters(new string[] { "," });
 csvParser.HasFieldsEnclosedInQuotes = true;

 // Skip the row with the column names
 csvParser.ReadLine();

 while (!csvParser.EndOfData)
 {
  // Read current line fields, pointer moves to the next line.
  string[] fields = csvParser.ReadFields();
  string Name = fields[0];
  string Address = fields[1];
 }
}

Remember to add reference to Microsoft.VisualBasic

记得添加对Microsoft.VisualBasic的引用

More details about the parser is given here: http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html

关于解析器的更多细节如下:http://codeskaters.blogspot.ae5/11/c - easy -csv-parser- build -in-net.html

#3


70  

LINQ way:

LINQ:

var lines = File.ReadAllLines("test.txt").Select(a => a.Split(';'));
var csv = from line in lines
          select (from piece in line
                  select piece);

^^Wrong - Edit by Nick

^ ^错误——编辑尼克

It appears the original answerer was attempting to populate csv with a 2 dimensional array - an array containing arrays. Each item in the first array contains an array representing that line number with each item in the nested array containing the data for that specific column.

似乎原来的answer erer试图用一个二维数组(一个包含数组的数组)填充csv。第一个数组中的每个项都包含一个数组,该数组表示嵌套数组中的每个条目的行号,其中包含特定列的数据。

var csv = from line in lines
          select (line.Split(',')).ToArray();

#4


32  

I usually use this parser from codeproject, since there's a bunch of character escapes and similar that it handles for me.

我通常使用这个来自codeproject的解析器,因为它为我处理了很多字符转义和类似的东西。

#5


27  

Here is my variation of the top voted answer:

以下是我对投票结果的变化:

var contents = File.ReadAllText(filename).Split('\n');
var csv = from line in contents
          select line.Split(',').ToArray();

The csv variable can then be used as in the following example:

然后可以使用csv变量,如下例所示:

int headerRows = 5;
foreach (var row in csv.Skip(headerRows)
    .TakeWhile(r => r.Length > 1 && r.Last().Trim().Length > 0))
{
    String zerothColumnValue = row[0]; // leftmost column
    var firstColumnValue = row[1];
}

#6


22  

You can't create an array immediately because you need to know the number of rows from the beginning (and this would require to read the csv file twice)

您不能立即创建数组,因为您需要从一开始就知道行数(这需要读取两次csv文件)

You can store values in two List<T> and then use them or convert into an array using List<T>.ToArray()

可以将值存储在两个列表 中,然后使用它们,或者使用List .ToArray()将它们转换为数组

Very simple example:

很简单的例子:

var column1 = new List<string>();
var column2 = new List<string>();
using (var rd = new StreamReader("filename.csv"))
{
    while (!rd.EndOfStream)
    {
        var splits = rd.ReadLine().Split(';');
        column1.Add(splits[0]);
        column2.Add(splits[1]);
    }
}
// print column1
Console.WriteLine("Column 1:");
foreach (var element in column1)
    Console.WriteLine(element);

// print column2
Console.WriteLine("Column 2:");
foreach (var element in column2)
    Console.WriteLine(element);

#7


21  

Just came across this library: https://github.com/JoshClose/CsvHelper

刚刚遇到这个库:https://github.com/JoshClose/CsvHelper

Very intuitive and easy to use. Has a nuget package too which made is quick to implement: http://nuget.org/packages/CsvHelper/1.17.0. Also appears to be actively maintained which I like.

非常直观,易于使用。也有一个nuget包,它可以快速实现:http://nuget.org/packages/CsvHelper/1.17.0。也似乎是积极维护,我喜欢。

Configuring it to use a semi-colon is easy: https://github.com/JoshClose/CsvHelper/wiki/Custom-Configurations

配置它使用分号很容易:https://github.com/joshclose/csvhelper/wiki/customconfigurations

#8


11  

If you need to skip (head-)lines and/or columns, you can use this to create a 2-dimensional array:

如果您需要跳过(head-)行和/或列,您可以使用它创建一个二维数组:

    var lines = File.ReadAllLines(path).Select(a => a.Split(';'));
    var csv = (from line in lines               
               select (from col in line
               select col).Skip(1).ToArray() // skip the first column
              ).Skip(2).ToArray(); // skip 2 headlines

This is quite useful if you need to shape the data before you process it further (assuming the first 2 lines consist of the headline, and the first column is a row title - which you don't need to have in the array because you just want to regard the data).

这是很有用的,如果你需要进一步形状数据前处理(假设的前2行包含标题,第一列是一行标题——你不需要数组中,因为你只是想把数据)。

N.B. You can easily get the headlines and the 1st column by using the following code:

注意:您可以使用以下代码轻松获取标题和第一栏:

    var coltitle = (from line in lines 
                    select line.Skip(1).ToArray() // skip 1st column
                   ).Skip(1).Take(1).FirstOrDefault().ToArray(); // take the 2nd row
    var rowtitle = (from line in lines select line[0] // take 1st column
                   ).Skip(2).ToArray(); // skip 2 headlines

This code example assumes the following structure of your *.csv file:

这个代码示例假设您的*具有以下结构。csv文件:

读取CSV文件并将值存储到数组中

Note: If you need to skip empty rows - which can by handy sometimes, you can do so by inserting

注意:如果您需要跳过空行——这有时很方便,您可以插入

    where line.Any(a=>!string.IsNullOrWhiteSpace(a))

between the from and the select statement in the LINQ code examples above.

在上面的LINQ代码示例中的from和select语句之间。

#9


8  

You can use Microsoft.VisualBasic.FileIO.TextFieldParser dll in C# for better performance

您可以使用Microsoft.VisualBasic.FileIO。c#中的TextFieldParser dll以获得更好的性能

get below code example from above article

从上面的文章中得到下面的代码示例

static void Main()
{
    string csv_file_path=@"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;
}

#10


4  

Here's a special case where one of data field has semicolon (";") as part of it's data in that case most of answers above will fail.

这里有一个特殊的情况,其中一个数据字段有分号(";")作为数据的一部分,在这种情况下,上面的大多数答案都会失败。

Solution it that case will be

解决这个问题

string[] csvRows = System.IO.File.ReadAllLines(FullyQaulifiedFileName);
string[] fields = null;
List<string> lstFields;
string field;
bool quoteStarted = false;
foreach (string csvRow in csvRows)
{
    lstFields = new List<string>();
    field = "";
    for (int i = 0; i < csvRow.Length; i++)
    {
        string tmp = csvRow.ElementAt(i).ToString();
        if(String.Compare(tmp,"\"")==0)
        {
            quoteStarted = !quoteStarted;
        }
        if (String.Compare(tmp, ";") == 0 && !quoteStarted)
        {
            lstFields.Add(field);
            field = "";
        }
        else if (String.Compare(tmp, "\"") != 0)
        {
            field += tmp;
        }
    }
    if(!string.IsNullOrEmpty(field))
    {
        lstFields.Add(field);
        field = "";
    }
// This will hold values for each column for current row under processing
    fields = lstFields.ToArray(); 
}

#11


3  

Hi all, I created a static class for doing this. + column check + quota sign removal

大家好,我为此创建了一个静态类。+列检查+配额符号删除

public static class CSV
{
    public static List<string[]> Import(string file, char csvDelimiter, bool ignoreHeadline, bool removeQuoteSign)
    {
        return ReadCSVFile(file, csvDelimiter, ignoreHeadline, removeQuoteSign);
    }

    private static List<string[]> ReadCSVFile(string filename, char csvDelimiter, bool ignoreHeadline, bool removeQuoteSign)
    {
        string[] result = new string[0];
        List<string[]> lst = new List<string[]>();

        string line;
        int currentLineNumner = 0;
        int columnCount = 0;

        // Read the file and display it line by line.  
        using (System.IO.StreamReader file = new System.IO.StreamReader(filename))
        {
            while ((line = file.ReadLine()) != null)
            {
                currentLineNumner++;
                string[] strAr = line.Split(csvDelimiter);
                // save column count of dirst line
                if (currentLineNumner == 1)
                {
                    columnCount = strAr.Count();
                }
                else
                {
                    //Check column count of every other lines
                    if (strAr.Count() != columnCount)
                    {
                        throw new Exception(string.Format("CSV Import Exception: Wrong column count in line {0}", currentLineNumner));
                    }
                }

                if (removeQuoteSign) strAr = RemoveQouteSign(strAr);

                if (ignoreHeadline)
                {
                    if(currentLineNumner !=1) lst.Add(strAr);
                }
                else
                {
                    lst.Add(strAr);
                }
            }

        }

        return lst;
    }
    private static string[] RemoveQouteSign(string[] ar)
    {
        for (int i = 0;i< ar.Count() ; i++)
        {
            if (ar[i].StartsWith("\"") || ar[i].StartsWith("'")) ar[i] = ar[i].Substring(1);
            if (ar[i].EndsWith("\"") || ar[i].EndsWith("'")) ar[i] = ar[i].Substring(0,ar[i].Length-1);

        }
        return ar;
    }

}

#12


2  

var firstColumn = new List<string>();
var lastColumn = new List<string>();

// your code for reading CSV file

foreach(var line in file)
{
    var array = line.Split(';');
    firstColumn.Add(array[0]);
    lastColumn.Add(array[1]);
}

var firstArray = firstColumn.ToArray();
var lastArray = lastColumn.ToArray();

#13


2  

The open-source Angara.Table library allows to load CSV into typed columns, so you can get the arrays from the columns. Each column can be indexed both by name or index. See http://predictionmachines.github.io/Angara.Table/saveload.html.

开源安加拉河。表库允许将CSV加载到类型化列中,因此可以从列中获取数组。每个列都可以按名称或索引进行索引。见http://predictionmachines.github.io/Angara.Table/saveload.html。

The library follows RFC4180 for CSV; it enables type inference and multiline strings.

该库遵循RFC4180的CSV;它支持类型推断和多行字符串。

Example:

例子:

using System.Collections.Immutable;
using Angara.Data;
using Angara.Data.DelimitedFile;

...

ReadSettings settings = new ReadSettings(Delimiter.Semicolon, false, true, null, null);
Table table = Table.Load("data.csv", settings);
ImmutableArray<double> a = table["double-column-name"].Rows.AsReal;

for(int i = 0; i < a.Length; i++)
{
    Console.WriteLine("{0}: {1}", i, a[i]);
}

You can see a column type using the type Column, e.g.

可以使用type列看到列类型,例如。

Column c = table["double-column-name"];
Console.WriteLine("Column {0} is double: {1}", c.Name, c.Rows.IsRealColumn);

Since the library is focused on F#, you might need to add a reference to the FSharp.Core 4.4 assembly; click 'Add Reference' on the project and choose FSharp.Core 4.4 under "Assemblies" -> "Extensions".

由于库集中在f#上,您可能需要向FSharp添加一个引用。4.4核心组装;点击项目“添加参考”,选择FSharp。核心4.4在“程序集”->“扩展”下。

#14


1  

I have been using csvreader.com(paid component) for years, and I have never had a problem. It is solid, small and fast, but you do have to pay for it. You can set the delimiter to whatever you like.

多年来,我一直在使用csvreader.com(付费组件),我从来没有遇到过问题。它坚固、小巧、快速,但你必须为此付出代价。您可以将分隔符设置为您喜欢的任何类型。

using (CsvReader reader = new CsvReader(s) {
    reader.Settings.Delimiter = ';';
    reader.ReadHeaders();  // if headers on a line by themselves.  Makes reader.Headers[] available
    while (reader.ReadRecord())
        ... use reader.Values[col_i] ...
}

#15


0  

Still wrong. You need to compensate for "" in quotes. Here is my solution Microsoft style csv.

仍然是错误的。你需要对引号中的“”进行补偿。这是我的解决方案微软风格的csv。

               /// <summary>
    /// Microsoft style csv file.  " is the quote character, "" is an escaped quote.
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="sepChar"></param>
    /// <param name="quoteChar"></param>
    /// <param name="escChar"></param>
    /// <returns></returns>
    public static List<string[]> ReadCSVFileMSStyle(string fileName, char sepChar = ',', char quoteChar = '"')
    {
        List<string[]> ret = new List<string[]>();

        string[] csvRows = System.IO.File.ReadAllLines(fileName);

        foreach (string csvRow in csvRows)
        {
            bool inQuotes = false;
            List<string> fields = new List<string>();
            string field = "";
            for (int i = 0; i < csvRow.Length; i++)
            {
                if (inQuotes)
                {
                    // Is it a "" inside quoted area? (escaped litteral quote)
                    if(i < csvRow.Length - 1 && csvRow[i] == quoteChar && csvRow[i+1] == quoteChar)
                    {
                        i++;
                        field += quoteChar;
                    }
                    else if(csvRow[i] == quoteChar)
                    {
                        inQuotes = false;
                    }
                    else
                    {
                        field += csvRow[i];
                    }
                }
                else // Not in quoted region
                {
                     if (csvRow[i] == quoteChar)
                    {
                        inQuotes = true;
                    }
                    if (csvRow[i] == sepChar)
                    {
                        fields.Add(field);
                        field = "";
                    }
                    else 
                    {
                        field += csvRow[i];
                    }
                }
            }
            if (!string.IsNullOrEmpty(field))
            {
                fields.Add(field);
                field = "";
            }
            ret.Add(fields.ToArray());
        }

        return ret;
    }
}

#16


0  

I am just student working on my master's thesis, but this is the way I solved it and it worked well for me. First you select your file from directory (only in csv format) and then you put the data into the lists.

我只是在做我的硕士论文的学生,但这是我解决它的方法,它对我很有效。首先从目录中选择文件(仅以csv格式),然后将数据放入列表。

List<float> t = new List<float>();
List<float> SensorI = new List<float>();
List<float> SensorII = new List<float>();
List<float> SensorIII = new List<float>();
using (OpenFileDialog dialog = new OpenFileDialog())
{
    try
    {
        dialog.Filter = "csv files (*.csv)|*.csv";
        dialog.Multiselect = false;
        dialog.InitialDirectory = ".";
        dialog.Title = "Select file (only in csv format)";
        if (dialog.ShowDialog() == DialogResult.OK)
        {
            var fs = File.ReadAllLines(dialog.FileName).Select(a => a.Split(';'));
            int counter = 0;
            foreach (var line in fs)
            {
                counter++;
                if (counter > 2)    // Skip first two headder lines
                {
                    this.t.Add(float.Parse(line[0]));
                    this.SensorI.Add(float.Parse(line[1]));
                    this.SensorII.Add(float.Parse(line[2]));
                    this.SensorIII.Add(float.Parse(line[3]));
                }
            }
        }
    }
    catch (Exception exc)
    {
        MessageBox.Show(
            "Error while opening the file.\n" + exc.Message, 
            this.Text, 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error
        );
    }
}

#17


0  

I have a library that is doing exactly you need.

我有一个图书馆正在做你需要的事情。

Some time ago I had wrote simple and fast enough library for work with CSV files. You can find it by the following link: https://github.com/ukushu/DataExporter

一段时间以前,我已经编写了足够简单和快速的库来处理CSV文件。您可以通过以下链接找到它:https://github.com/ukushu/dataexports

It works with CSV like with 2 dimensions array. Exactly like you need.

它与CSV类似于二维数组。你需要一模一样。

As example, in case of you need all of values of 3rd row only you need is to write:

例如,如果你需要所有的第3行值,你只需要写:

Csv csv = new Csv();

csv.FileOpen("c:\\file1.csv");

var allValuesOf3rdRow = csv.Rows[2];

or to read 2nd cell of

或者读第二个单元格

var value = csv.Rows[2][1];

#1


278  

You can do it like this:

你可以这样做:

using System.IO;

static void Main(string[] args)
{
    using(var reader = new StreamReader(@"C:\test.csv"))
    {
        List<string> listA = new List<string>();
        List<string> listB = new List<string>();
        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            var values = line.Split(';');

            listA.Add(values[0]);
            listB.Add(values[1]);
        }
    }
}

#2


72  

My favourite csv parser is one built into .net library. This is a hidden treasure inside Microsoft.VisualBasic namespace. Below is a sample code:

我最喜欢的csv解析器是内建在。net库中的。这是微软内部隐藏的宝藏。VisualBasic名称空间。下面是一个示例代码:

using Microsoft.VisualBasic.FileIO;

var path = @"C:\Person.csv"; // Habeeb, "Dubai Media City, Dubai"
using (TextFieldParser csvParser = new TextFieldParser(path))
{
 csvParser.CommentTokens = new string[] { "#" };
 csvParser.SetDelimiters(new string[] { "," });
 csvParser.HasFieldsEnclosedInQuotes = true;

 // Skip the row with the column names
 csvParser.ReadLine();

 while (!csvParser.EndOfData)
 {
  // Read current line fields, pointer moves to the next line.
  string[] fields = csvParser.ReadFields();
  string Name = fields[0];
  string Address = fields[1];
 }
}

Remember to add reference to Microsoft.VisualBasic

记得添加对Microsoft.VisualBasic的引用

More details about the parser is given here: http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html

关于解析器的更多细节如下:http://codeskaters.blogspot.ae5/11/c - easy -csv-parser- build -in-net.html

#3


70  

LINQ way:

LINQ:

var lines = File.ReadAllLines("test.txt").Select(a => a.Split(';'));
var csv = from line in lines
          select (from piece in line
                  select piece);

^^Wrong - Edit by Nick

^ ^错误——编辑尼克

It appears the original answerer was attempting to populate csv with a 2 dimensional array - an array containing arrays. Each item in the first array contains an array representing that line number with each item in the nested array containing the data for that specific column.

似乎原来的answer erer试图用一个二维数组(一个包含数组的数组)填充csv。第一个数组中的每个项都包含一个数组,该数组表示嵌套数组中的每个条目的行号,其中包含特定列的数据。

var csv = from line in lines
          select (line.Split(',')).ToArray();

#4


32  

I usually use this parser from codeproject, since there's a bunch of character escapes and similar that it handles for me.

我通常使用这个来自codeproject的解析器,因为它为我处理了很多字符转义和类似的东西。

#5


27  

Here is my variation of the top voted answer:

以下是我对投票结果的变化:

var contents = File.ReadAllText(filename).Split('\n');
var csv = from line in contents
          select line.Split(',').ToArray();

The csv variable can then be used as in the following example:

然后可以使用csv变量,如下例所示:

int headerRows = 5;
foreach (var row in csv.Skip(headerRows)
    .TakeWhile(r => r.Length > 1 && r.Last().Trim().Length > 0))
{
    String zerothColumnValue = row[0]; // leftmost column
    var firstColumnValue = row[1];
}

#6


22  

You can't create an array immediately because you need to know the number of rows from the beginning (and this would require to read the csv file twice)

您不能立即创建数组,因为您需要从一开始就知道行数(这需要读取两次csv文件)

You can store values in two List<T> and then use them or convert into an array using List<T>.ToArray()

可以将值存储在两个列表 中,然后使用它们,或者使用List .ToArray()将它们转换为数组

Very simple example:

很简单的例子:

var column1 = new List<string>();
var column2 = new List<string>();
using (var rd = new StreamReader("filename.csv"))
{
    while (!rd.EndOfStream)
    {
        var splits = rd.ReadLine().Split(';');
        column1.Add(splits[0]);
        column2.Add(splits[1]);
    }
}
// print column1
Console.WriteLine("Column 1:");
foreach (var element in column1)
    Console.WriteLine(element);

// print column2
Console.WriteLine("Column 2:");
foreach (var element in column2)
    Console.WriteLine(element);

#7


21  

Just came across this library: https://github.com/JoshClose/CsvHelper

刚刚遇到这个库:https://github.com/JoshClose/CsvHelper

Very intuitive and easy to use. Has a nuget package too which made is quick to implement: http://nuget.org/packages/CsvHelper/1.17.0. Also appears to be actively maintained which I like.

非常直观,易于使用。也有一个nuget包,它可以快速实现:http://nuget.org/packages/CsvHelper/1.17.0。也似乎是积极维护,我喜欢。

Configuring it to use a semi-colon is easy: https://github.com/JoshClose/CsvHelper/wiki/Custom-Configurations

配置它使用分号很容易:https://github.com/joshclose/csvhelper/wiki/customconfigurations

#8


11  

If you need to skip (head-)lines and/or columns, you can use this to create a 2-dimensional array:

如果您需要跳过(head-)行和/或列,您可以使用它创建一个二维数组:

    var lines = File.ReadAllLines(path).Select(a => a.Split(';'));
    var csv = (from line in lines               
               select (from col in line
               select col).Skip(1).ToArray() // skip the first column
              ).Skip(2).ToArray(); // skip 2 headlines

This is quite useful if you need to shape the data before you process it further (assuming the first 2 lines consist of the headline, and the first column is a row title - which you don't need to have in the array because you just want to regard the data).

这是很有用的,如果你需要进一步形状数据前处理(假设的前2行包含标题,第一列是一行标题——你不需要数组中,因为你只是想把数据)。

N.B. You can easily get the headlines and the 1st column by using the following code:

注意:您可以使用以下代码轻松获取标题和第一栏:

    var coltitle = (from line in lines 
                    select line.Skip(1).ToArray() // skip 1st column
                   ).Skip(1).Take(1).FirstOrDefault().ToArray(); // take the 2nd row
    var rowtitle = (from line in lines select line[0] // take 1st column
                   ).Skip(2).ToArray(); // skip 2 headlines

This code example assumes the following structure of your *.csv file:

这个代码示例假设您的*具有以下结构。csv文件:

读取CSV文件并将值存储到数组中

Note: If you need to skip empty rows - which can by handy sometimes, you can do so by inserting

注意:如果您需要跳过空行——这有时很方便,您可以插入

    where line.Any(a=>!string.IsNullOrWhiteSpace(a))

between the from and the select statement in the LINQ code examples above.

在上面的LINQ代码示例中的from和select语句之间。

#9


8  

You can use Microsoft.VisualBasic.FileIO.TextFieldParser dll in C# for better performance

您可以使用Microsoft.VisualBasic.FileIO。c#中的TextFieldParser dll以获得更好的性能

get below code example from above article

从上面的文章中得到下面的代码示例

static void Main()
{
    string csv_file_path=@"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;
}

#10


4  

Here's a special case where one of data field has semicolon (";") as part of it's data in that case most of answers above will fail.

这里有一个特殊的情况,其中一个数据字段有分号(";")作为数据的一部分,在这种情况下,上面的大多数答案都会失败。

Solution it that case will be

解决这个问题

string[] csvRows = System.IO.File.ReadAllLines(FullyQaulifiedFileName);
string[] fields = null;
List<string> lstFields;
string field;
bool quoteStarted = false;
foreach (string csvRow in csvRows)
{
    lstFields = new List<string>();
    field = "";
    for (int i = 0; i < csvRow.Length; i++)
    {
        string tmp = csvRow.ElementAt(i).ToString();
        if(String.Compare(tmp,"\"")==0)
        {
            quoteStarted = !quoteStarted;
        }
        if (String.Compare(tmp, ";") == 0 && !quoteStarted)
        {
            lstFields.Add(field);
            field = "";
        }
        else if (String.Compare(tmp, "\"") != 0)
        {
            field += tmp;
        }
    }
    if(!string.IsNullOrEmpty(field))
    {
        lstFields.Add(field);
        field = "";
    }
// This will hold values for each column for current row under processing
    fields = lstFields.ToArray(); 
}

#11


3  

Hi all, I created a static class for doing this. + column check + quota sign removal

大家好,我为此创建了一个静态类。+列检查+配额符号删除

public static class CSV
{
    public static List<string[]> Import(string file, char csvDelimiter, bool ignoreHeadline, bool removeQuoteSign)
    {
        return ReadCSVFile(file, csvDelimiter, ignoreHeadline, removeQuoteSign);
    }

    private static List<string[]> ReadCSVFile(string filename, char csvDelimiter, bool ignoreHeadline, bool removeQuoteSign)
    {
        string[] result = new string[0];
        List<string[]> lst = new List<string[]>();

        string line;
        int currentLineNumner = 0;
        int columnCount = 0;

        // Read the file and display it line by line.  
        using (System.IO.StreamReader file = new System.IO.StreamReader(filename))
        {
            while ((line = file.ReadLine()) != null)
            {
                currentLineNumner++;
                string[] strAr = line.Split(csvDelimiter);
                // save column count of dirst line
                if (currentLineNumner == 1)
                {
                    columnCount = strAr.Count();
                }
                else
                {
                    //Check column count of every other lines
                    if (strAr.Count() != columnCount)
                    {
                        throw new Exception(string.Format("CSV Import Exception: Wrong column count in line {0}", currentLineNumner));
                    }
                }

                if (removeQuoteSign) strAr = RemoveQouteSign(strAr);

                if (ignoreHeadline)
                {
                    if(currentLineNumner !=1) lst.Add(strAr);
                }
                else
                {
                    lst.Add(strAr);
                }
            }

        }

        return lst;
    }
    private static string[] RemoveQouteSign(string[] ar)
    {
        for (int i = 0;i< ar.Count() ; i++)
        {
            if (ar[i].StartsWith("\"") || ar[i].StartsWith("'")) ar[i] = ar[i].Substring(1);
            if (ar[i].EndsWith("\"") || ar[i].EndsWith("'")) ar[i] = ar[i].Substring(0,ar[i].Length-1);

        }
        return ar;
    }

}

#12


2  

var firstColumn = new List<string>();
var lastColumn = new List<string>();

// your code for reading CSV file

foreach(var line in file)
{
    var array = line.Split(';');
    firstColumn.Add(array[0]);
    lastColumn.Add(array[1]);
}

var firstArray = firstColumn.ToArray();
var lastArray = lastColumn.ToArray();

#13


2  

The open-source Angara.Table library allows to load CSV into typed columns, so you can get the arrays from the columns. Each column can be indexed both by name or index. See http://predictionmachines.github.io/Angara.Table/saveload.html.

开源安加拉河。表库允许将CSV加载到类型化列中,因此可以从列中获取数组。每个列都可以按名称或索引进行索引。见http://predictionmachines.github.io/Angara.Table/saveload.html。

The library follows RFC4180 for CSV; it enables type inference and multiline strings.

该库遵循RFC4180的CSV;它支持类型推断和多行字符串。

Example:

例子:

using System.Collections.Immutable;
using Angara.Data;
using Angara.Data.DelimitedFile;

...

ReadSettings settings = new ReadSettings(Delimiter.Semicolon, false, true, null, null);
Table table = Table.Load("data.csv", settings);
ImmutableArray<double> a = table["double-column-name"].Rows.AsReal;

for(int i = 0; i < a.Length; i++)
{
    Console.WriteLine("{0}: {1}", i, a[i]);
}

You can see a column type using the type Column, e.g.

可以使用type列看到列类型,例如。

Column c = table["double-column-name"];
Console.WriteLine("Column {0} is double: {1}", c.Name, c.Rows.IsRealColumn);

Since the library is focused on F#, you might need to add a reference to the FSharp.Core 4.4 assembly; click 'Add Reference' on the project and choose FSharp.Core 4.4 under "Assemblies" -> "Extensions".

由于库集中在f#上,您可能需要向FSharp添加一个引用。4.4核心组装;点击项目“添加参考”,选择FSharp。核心4.4在“程序集”->“扩展”下。

#14


1  

I have been using csvreader.com(paid component) for years, and I have never had a problem. It is solid, small and fast, but you do have to pay for it. You can set the delimiter to whatever you like.

多年来,我一直在使用csvreader.com(付费组件),我从来没有遇到过问题。它坚固、小巧、快速,但你必须为此付出代价。您可以将分隔符设置为您喜欢的任何类型。

using (CsvReader reader = new CsvReader(s) {
    reader.Settings.Delimiter = ';';
    reader.ReadHeaders();  // if headers on a line by themselves.  Makes reader.Headers[] available
    while (reader.ReadRecord())
        ... use reader.Values[col_i] ...
}

#15


0  

Still wrong. You need to compensate for "" in quotes. Here is my solution Microsoft style csv.

仍然是错误的。你需要对引号中的“”进行补偿。这是我的解决方案微软风格的csv。

               /// <summary>
    /// Microsoft style csv file.  " is the quote character, "" is an escaped quote.
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="sepChar"></param>
    /// <param name="quoteChar"></param>
    /// <param name="escChar"></param>
    /// <returns></returns>
    public static List<string[]> ReadCSVFileMSStyle(string fileName, char sepChar = ',', char quoteChar = '"')
    {
        List<string[]> ret = new List<string[]>();

        string[] csvRows = System.IO.File.ReadAllLines(fileName);

        foreach (string csvRow in csvRows)
        {
            bool inQuotes = false;
            List<string> fields = new List<string>();
            string field = "";
            for (int i = 0; i < csvRow.Length; i++)
            {
                if (inQuotes)
                {
                    // Is it a "" inside quoted area? (escaped litteral quote)
                    if(i < csvRow.Length - 1 && csvRow[i] == quoteChar && csvRow[i+1] == quoteChar)
                    {
                        i++;
                        field += quoteChar;
                    }
                    else if(csvRow[i] == quoteChar)
                    {
                        inQuotes = false;
                    }
                    else
                    {
                        field += csvRow[i];
                    }
                }
                else // Not in quoted region
                {
                     if (csvRow[i] == quoteChar)
                    {
                        inQuotes = true;
                    }
                    if (csvRow[i] == sepChar)
                    {
                        fields.Add(field);
                        field = "";
                    }
                    else 
                    {
                        field += csvRow[i];
                    }
                }
            }
            if (!string.IsNullOrEmpty(field))
            {
                fields.Add(field);
                field = "";
            }
            ret.Add(fields.ToArray());
        }

        return ret;
    }
}

#16


0  

I am just student working on my master's thesis, but this is the way I solved it and it worked well for me. First you select your file from directory (only in csv format) and then you put the data into the lists.

我只是在做我的硕士论文的学生,但这是我解决它的方法,它对我很有效。首先从目录中选择文件(仅以csv格式),然后将数据放入列表。

List<float> t = new List<float>();
List<float> SensorI = new List<float>();
List<float> SensorII = new List<float>();
List<float> SensorIII = new List<float>();
using (OpenFileDialog dialog = new OpenFileDialog())
{
    try
    {
        dialog.Filter = "csv files (*.csv)|*.csv";
        dialog.Multiselect = false;
        dialog.InitialDirectory = ".";
        dialog.Title = "Select file (only in csv format)";
        if (dialog.ShowDialog() == DialogResult.OK)
        {
            var fs = File.ReadAllLines(dialog.FileName).Select(a => a.Split(';'));
            int counter = 0;
            foreach (var line in fs)
            {
                counter++;
                if (counter > 2)    // Skip first two headder lines
                {
                    this.t.Add(float.Parse(line[0]));
                    this.SensorI.Add(float.Parse(line[1]));
                    this.SensorII.Add(float.Parse(line[2]));
                    this.SensorIII.Add(float.Parse(line[3]));
                }
            }
        }
    }
    catch (Exception exc)
    {
        MessageBox.Show(
            "Error while opening the file.\n" + exc.Message, 
            this.Text, 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error
        );
    }
}

#17


0  

I have a library that is doing exactly you need.

我有一个图书馆正在做你需要的事情。

Some time ago I had wrote simple and fast enough library for work with CSV files. You can find it by the following link: https://github.com/ukushu/DataExporter

一段时间以前,我已经编写了足够简单和快速的库来处理CSV文件。您可以通过以下链接找到它:https://github.com/ukushu/dataexports

It works with CSV like with 2 dimensions array. Exactly like you need.

它与CSV类似于二维数组。你需要一模一样。

As example, in case of you need all of values of 3rd row only you need is to write:

例如,如果你需要所有的第3行值,你只需要写:

Csv csv = new Csv();

csv.FileOpen("c:\\file1.csv");

var allValuesOf3rdRow = csv.Rows[2];

or to read 2nd cell of

或者读第二个单元格

var value = csv.Rows[2][1];