Đọc tệp CSV và lưu trữ giá trị vào một mảng


317

Tôi đang cố đọc một *.csv-file.

Tệp *.csv-file bao gồm hai cột được phân tách bằng dấu chấm phẩy (" ; ").

Tôi có thể đọc *.csv-file bằng StreamReader và có thể tách từng dòng bằng cách sử dụng Split()hàm. Tôi muốn lưu trữ mỗi cột thành một mảng riêng biệt và sau đó hiển thị nó.

Có thể làm điều đó?


2
@Marc: tiếc là trong các nền văn hóa không phải tiếng Anh (ví dụ như tiếng Ý) khi bạn tiết kiệm một excel để CSV nó sử dụng ";"như tách ... này đã làm cho CSV một phi tiêu chuẩn imo :(
digEmAll

25
Tôi luôn đọc CSV dưới dạng các giá trị được phân tách bằng ký tự vì mọi người gọi tệp CSV ngay cả khi họ không sử dụng dấu phẩy làm dấu phân cách. Và có rất nhiều phương ngữ với các quy tắc trích dẫn hoặc thoát khác nhau trong thực tế đến mức bạn không thể thực sự nói về một tiêu chuẩn ngay cả khi trên lý thuyết có RFC.
CodeInChaos

1
Tên tiện ích mở rộng tệp CSV bây giờ sẽ được thay đổi thành DSV - Tệp giá trị phân tách dấu phân cách
Ambuj

Đối với tất cả các câu trả lời chỉ đơn giản là tách chuỗi trên ký tự phân cách, đây không phải là cách tốt nhất để đi. Có nhiều quy tắc hơn đối với định dạng CSV mà điều này sẽ không bao gồm. Tốt nhất là sử dụng trình phân tích cú pháp của bên thứ 3. Thêm thông tin- dotnetcoretutorials.com/2018/08/04/csv-parsing-in-net-core
iliketocode

Câu trả lời:


415

Bạn có thể làm như thế này:

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

5
Cảm ơn vì điều này, tôi đã quên cách chia dòng trong tệp csv (câm tôi!) Nhưng giải pháp của bạn đã giúp tôi :)
Hallaghan

4
Đã hơn 3 năm sau và câu hỏi này vẫn đang giúp ai đó. Tôi cảm thấy tồi tệ vì bạn đã không chấp nhận điều này.
AdamMc331

12
Không xử lý các giá trị trường bằng dấu phẩy, v.v.
Mike

12
Nên sử dụng một usingkhoản ở đây, hoặc tại một cách thủ công rất ít Close()các readervì nó là một IDisposibletài nguyên.
Assaf Israel

30
Điều này cũng sẽ không phân tích chính xác một CSV được viết như column1;"Special ; char in string";column3- tools.ietf.org/html/rfc4180
Ole K

173

Trình phân tích cú pháp CSV yêu thích của tôi là một trình tích hợp vào thư viện .NET. Đây là một kho báu ẩn bên trong không gian tên Microsoft.VisualBasic. Dưới đây là một mã mẫu:

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

Nhớ thêm tham chiếu đến Microsoft.VisualBasic

Thông tin chi tiết về trình phân tích cú pháp được cung cấp tại đây: http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html


6
Tôi thích tùy chọn này là tốt nhất. Tôi không phải lo lắng về các ký tự thoát vì lớp là trình phân tích cú pháp CSV và không phải là thứ được xây dựng thủ công.
Timothy Gonzalez

22
Trong trường hợp bất kỳ ai gặp phải vấn đề này và đang tự hỏi, bạn sẽ cần bao gồm tham chiếu đến Microsoft.VisualBasiclắp ráp khung vì nó thường không được tham chiếu theo mặc định.
apokryfos

3
Tôi ước tôi đã nhớ điều này từ VB6 ngày của tôi, sẽ giúp tôi tiết kiệm rất nhiều thời gian trong những năm qua. Mặc dù một số người sẽ nói về VB, nhưng tôi không có vấn đề gì khi thêm dll & không gian tên vào mã của tôi nếu nó có giá trị. Điều này có rất nhiều giá trị.
Walter

2
Giải pháp này là một homerun. trình phân tích cú pháp rất đáng tin cậy từ kinh nghiệm của tôi.
Glenn Ferrie

3
Tại sao chỉ có trong dll VB?
Đánh dấu

75

Cách LINQ:

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

^^ Sai - Chỉnh sửa bởi Nick

Có vẻ như người trả lời ban đầu đang cố gắng tạo ra csvmột mảng 2 chiều - một mảng chứa các mảng. Mỗi mục trong mảng đầu tiên chứa một mảng biểu thị số dòng đó với mỗi mục trong mảng lồng nhau chứa dữ liệu cho cột cụ thể đó.

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

2
Có thể tôi đang thiếu một cái gì đó, nhưng tôi không chắc điểm của biến csv của bạn là gì - không phải bạn chỉ đang tạo lại cấu trúc dữ liệu tương tự được đọc trong các dòng sao?
Ben Hughes

13
@ClayShannon .NET 1.1? Tôi ... rất xin lỗi bạn.
contactmatt

5
@contactmatt: Tôi sẽ không làm bạn thất vọng về tình cảm đó.
B. Clay Shannon

9
Tôi cũng muốn chỉ ra rằng csv có thể được trích dẫn ... Vì vậy, sử dụng chuỗi.Split không phải là một lựa chọn khả thi.
Alxandr

5
Tôi đang nhận được: 'System.Array' không chứa định nghĩa cho 'Split' và không có phương thức mở rộng 'Split' chấp nhận đối số đầu tiên của loại 'System.Array' (bạn có thể thiếu tham chiếu lệnh hoặc tham chiếu lắp ráp ?)
Kala J

36

Bạn không thể tạo một mảng ngay lập tức vì bạn cần biết số lượng hàng ngay từ đầu (và điều này sẽ yêu cầu đọc tệp csv hai lần)

Bạn có thể lưu trữ giá trị thành hai List<T>và sau đó sử dụng chúng hoặc chuyển đổi thành một mảng bằng cách sử dụngList<T>.ToArray()

Ví dụ rất đơn giản:

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

Lưu ý

Xin lưu ý rằng đây chỉ là một ví dụ rất đơn giản . Việc sử dụng string.Splitkhông tính đến các trường hợp một số bản ghi chứa dấu phân cách ;bên trong nó.
Để tiếp cận an toàn hơn, hãy xem xét sử dụng một số thư viện cụ thể của csv như CsvHelper trên nuget.


Không chiếm ;một phần của giá trị, ví dụ "value with ; inside it". Các giá trị bao quanh CSV chứa các ký tự đặc biệt có dấu ngoặc kép để nói rằng đó là một chuỗi ký tự.
ChickenFeet

1
@ChickenFeet: chắc chắn, đó là lý do của chú thích: "Ví dụ rất đơn giản" . Dù sao tôi cũng có thể thêm một ghi chú về điều đó;)
digEmAll 12/12/18

Đừng lo lắng, tôi nhận thấy rất nhiều câu trả lời khác ở đây cũng không tính đến nó :)
ChickenFeet 12/12/18

1
Regex.Split (sr.ReadLine (), ", (? = (?: [^ \"] * \ "[^ \"] * \ ") * [^ \"] * $) "); // Đã tìm thấy cái này trên SO ... nhanh hơn một thư viện.
Pinch

34

Vừa đi qua thư viện này: https://github.com/JoshClose/CsvHelper

Rất trực quan và dễ sử dụng. Có một gói nuget cũng được thực hiện nhanh chóng: http://nuget.org/packages/CsvHelper/1.17.0 . Cũng xuất hiện để được duy trì tích cực mà tôi thích.

Việc định cấu hình để sử dụng dấu chấm phẩy rất dễ dàng: https://github.com/JoshClose/CsvHelper/wiki/Custom-Configurations


3
Đây là câu trả lời tốt nhất! Thư viện mạnh mẽ dễ dàng thả vào và cuộn lại.
Tyler Forsythe

3
Thư viện CsvHelper thật tuyệt vời. Siêu nhanh và dễ sử dụng.
Giáo xứ Steve

3
Nếu bạn đang tìm kiếm một thư viện có thể xử lý mọi khía cạnh của định dạng csv bao gồm các chuỗi được trích dẫn, hãy sử dụng thư viện này. Tuyệt vời!
Matt

Thx, thư viện thực sự tốt đẹp, dễ sử dụng và rất mạnh mẽ.
Sebastián Guerrero

2
Làm thế nào để hiệu suất so sánh với Microsoft.VisualBasic.FileIO.TextFieldParser(xem câu trả lời của @ Habeeb)?
bovender

33

Tôi thường sử dụng trình phân tích cú pháp này từ bảng mã , vì có một loạt các ký tự thoát và tương tự như nó xử lý cho tôi.


2
Điều này là rất tốt và nhanh chóng. Nếu bạn đang ở trong một tình huống kinh doanh và cần phải bẻ khóa, hãy sử dụng cái này.
gjvdkamp

8
Trình phân tích cú pháp này có sẵn trong bộ sưu tập Nuget với tên LumenWorks.Framework.IO, trong trường hợp bạn không muốn đăng ký CodeProject để tải xuống.
Greg McCoy

30

Đây là biến thể của tôi về câu trả lời được bình chọn hàng đầu:

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

Các csvbiến sau đó có thể được sử dụng như trong ví dụ sau:

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

Làm thế nào để bạn truy cập vào các hàng và cột trong biến csv?
Khóa Matthew

1
Làm thế nào để bạn xử lý thoát dấu phẩy?
Kuangwei Zhang

Không xử lý dấu phẩy trong các cột. Tốt hơn là sử dụng thư viện mạnh mẽ CsvHelper theo câu trả lời
Tim Partridge

11

Nếu bạn cần bỏ qua (head-) dòng và / hoặc cột, bạn có thể sử dụng điều này để tạo mảng 2 chiều:

    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

Điều này khá hữu ích nếu bạn cần định hình dữ liệu trước khi xử lý thêm (giả sử 2 dòng đầu tiên bao gồm tiêu đề và cột đầu tiên là tiêu đề hàng - mà bạn không cần phải có trong mảng vì bạn chỉ cần muốn liên quan đến dữ liệu).

NB Bạn có thể dễ dàng lấy các tiêu đề và cột thứ 1 bằng cách sử dụng mã sau:

    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

Ví dụ mã này giả định cấu trúc sau của *.csvtệp của bạn :

Ma trận CSV

Lưu ý: Nếu bạn cần bỏ qua các hàng trống - đôi khi có thể tiện dụng, bạn có thể làm như vậy bằng cách chèn

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

giữa fromselectcâu lệnh trong các ví dụ mã LINQ ở trên.


10

Bạn có thể sử dụng dll Microsoft.VisualBasic.FileIO.TextFieldParser trong C # để có hiệu suất tốt hơn

lấy ví dụ mã dưới đây từ bài viết trên

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

9
Nó không hiệu quả vì Split không làm mọi thứ mà TextFieldParser làm. Ví dụ: bỏ qua các dòng nhận xét, xử lý các trường được trích dẫn và xóa khoảng trắng bắt đầu / theo dõi. Không chính xác so sánh 1: 1.
Robert McKee

5

Xin chào, tôi đã tạo một lớp tĩnh để làm việc này. + kiểm tra cột + xóa bỏ hạn ngạch

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

}

4
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();

Cảm ơn bạn đã giúp đỡ. Nó có thể giúp giải quyết vấn đề của tôi. Thật ra tôi phải đọc dữ liệu từ tập tin rồi chèn vào cơ sở dữ liệu. Tại thời điểm chèn tôi đang gặp lỗi ràng buộc khóa chính (vì tôi đã có dữ liệu trong cơ sở dữ liệu). Vì vậy, tôi cần lập trình sao cho với biến đã tồn tại rồi cập nhật dữ liệu.
Rushabh Shah

Tôi giả sử giá trị đầu tiên nếu PK - bạn cần lấy một bản ghi theo id từ cơ sở dữ liệu và nếu nó tồn tại hơn là phát hành một câu lệnh CẬP NHẬT, nếu không thì chèn một bản ghi mới.
Jakub Konecki

3

Đây là trường hợp đặc biệt khi một trong các trường dữ liệu có dấu chấm phẩy (";") là một phần của dữ liệu trong trường hợp đó, hầu hết các câu trả lời ở trên sẽ không thành công.

Giải pháp cho trường hợp đó sẽ là

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

2

Thư viện Angara.Table mã nguồn mở cho phép tải CSV vào các cột được nhập, do đó bạn có thể lấy các mảng từ các cột. Mỗi cột có thể được lập chỉ mục theo cả tên hoặc chỉ mục. Xem http://predictionmachines.github.io/Angara.Table/saveload.html .

Thư viện theo RFC4180 cho CSV; nó cho phép suy luận kiểu và chuỗi đa dòng.

Thí dụ:

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

Bạn có thể thấy một loại cột bằng cách sử dụng loại Cột, vd

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

Vì thư viện tập trung vào F #, bạn có thể cần thêm một tham chiếu đến cụm FSharp.Core 4.4; nhấp vào 'Thêm tài liệu tham khảo' trên dự án và chọn FSharp.Core 4.4 trong phần "Lắp ráp" -> "Tiện ích mở rộng".


2

Tôi đã dành vài giờ để tìm kiếm một thư viện phù hợp, nhưng cuối cùng tôi đã viết mã của riêng mình :) Bạn có thể đọc tệp (hoặc cơ sở dữ liệu) với bất kỳ công cụ nào bạn muốn và sau đó áp dụng quy trình sau cho mỗi dòng:

private static string[] SmartSplit(string line, char separator = ',')
{
    var inQuotes = false;
    var token = "";
    var lines = new List<string>();
    for (var i = 0; i < line.Length; i++) {
        var ch = line[i];
        if (inQuotes) // process string in quotes, 
        {
            if (ch == '"') {
                if (i<line.Length-1 && line[i + 1] == '"') {
                    i++;
                    token += '"';
                }
                else inQuotes = false;
            } else token += ch;
        } else {
            if (ch == '"') inQuotes = true;
            else if (ch == separator) {
                lines.Add(token);
                token = "";
                } else token += ch;
            }
    }
    lines.Add(token);
    return lines.ToArray();
}

1

Tôi đã sử dụng csvreader.com (thành phần trả phí) trong nhiều năm và tôi chưa bao giờ gặp vấn đề gì. Nó là rắn, nhỏ và nhanh, nhưng bạn phải trả tiền cho nó. Bạn có thể đặt dấu phân cách thành bất cứ thứ gì bạn thích.

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] ...
}

1

Tôi chỉ là sinh viên làm luận án thạc sĩ, nhưng đây là cách tôi giải quyết và nó hoạt động tốt với tôi. Đầu tiên bạn chọn tệp của mình từ thư mục (chỉ ở định dạng csv) và sau đó bạn đưa dữ liệu vào danh sách.

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

0

Vẫn sai. Bạn cần phải bù cho "" trong dấu ngoặc kép. Đây là giải pháp của tôi theo phong cách csv của Microsoft.

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

3
Nó không xử lý trường hợp khi có dòng mới bên trong các giá trị cột;)
Emil

0

Tôi có một thư viện đang làm chính xác bạn cần.

Cách đây một thời gian, tôi đã viết thư viện đủ đơn giản và nhanh chóng để làm việc với các tệp CSV. Bạn có thể tìm thấy nó bằng liên kết sau: https://github.com/ukushu/DataExporter

Nó hoạt động với CSV như với mảng 2 chiều. Chính xác như bạn cần.

Ví dụ: trong trường hợp bạn cần tất cả các giá trị của hàng thứ 3, bạn chỉ cần viết:

Csv csv = new Csv();

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

var allValuesOf3rdRow = csv.Rows[2];

hoặc để đọc ô thứ 2 của

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

-1

nhìn này

sử dụng CsvFramework;

sử dụng System.Collections.Generic;

không gian tên CvsParser {

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Order> Orders { get; set; }        
}

public class Order
{
    public int Id { get; set; }

    public int CustomerId { get; set; }
    public int Quantity { get; set; }

    public int Amount { get; set; }

    public List<OrderItem> OrderItems { get; set; }

}

public class Address
{
    public int Id { get; set; }
    public int CustomerId { get; set; }

    public string Name { get; set; }
}

public class OrderItem
{
    public int Id { get; set; }
    public int OrderId { get; set; }

    public string ProductName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {

        var customerLines = System.IO.File.ReadAllLines(@"Customers.csv");
        var orderLines = System.IO.File.ReadAllLines(@"Orders.csv");
        var orderItemLines = System.IO.File.ReadAllLines(@"OrderItemLines.csv");

        CsvFactory.Register<Customer>(builder =>
        {
            builder.Add(a => a.Id).Type(typeof(int)).Index(0).IsKey(true);
            builder.Add(a => a.Name).Type(typeof(string)).Index(1);
            builder.AddNavigation(n => n.Orders).RelationKey<Order, int>(k => k.CustomerId);

        }, false, ',', customerLines);

        CsvFactory.Register<Order>(builder =>
        {
            builder.Add(a => a.Id).Type(typeof(int)).Index(0).IsKey(true);
            builder.Add(a => a.CustomerId).Type(typeof(int)).Index(1);
            builder.Add(a => a.Quantity).Type(typeof(int)).Index(2);
            builder.Add(a => a.Amount).Type(typeof(int)).Index(3);
            builder.AddNavigation(n => n.OrderItems).RelationKey<OrderItem, int>(k => k.OrderId);

        }, true, ',', orderLines);


        CsvFactory.Register<OrderItem>(builder =>
        {
            builder.Add(a => a.Id).Type(typeof(int)).Index(0).IsKey(true);
            builder.Add(a => a.OrderId).Type(typeof(int)).Index(1);
            builder.Add(a => a.ProductName).Type(typeof(string)).Index(2);


        }, false, ',', orderItemLines);



        var customers = CsvFactory.Parse<Customer>();


    }
}

}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.