อ่านไฟล์ CSV และเก็บค่าไว้ในอาร์เรย์


317

ฉันพยายามอ่าน *.csvไฟล์

*.csvแฟ้ม: ประกอบด้วยสองคอลัมน์คั่น (" ; ")

ฉันสามารถอ่าน*.csvไฟล์โดยใช้ StreamReader และสามารถแยกแต่ละบรรทัดโดยใช้Split()ฟังก์ชั่น ฉันต้องการเก็บแต่ละคอลัมน์ไว้ในอาร์เรย์ที่แยกต่างหากจากนั้นแสดง

เป็นไปได้ไหมที่จะทำเช่นนั้น?


2
@ Marc: โชคไม่ดีในวัฒนธรรมที่ไม่ใช่ภาษาอังกฤษ (เช่นภาษาอิตาลี) เมื่อคุณบันทึก excel ลงใน CSV จะใช้";"เป็นตัวแยก ... นี่ทำให้ CSV เป็น IMO ที่ไม่ได้มาตรฐาน :(
digEmAll

25
ฉันมักจะอ่าน CSV เป็นค่าที่คั่นด้วยตัวละครเพราะคนเรียกไฟล์ CSV แม้ว่าพวกเขาจะไม่ใช้เครื่องหมายจุลภาคเป็นตัวคั่น และมีภาษาถิ่นจำนวนมากที่มีการอ้างหรือหลบหนีกฎต่าง ๆ ในทางปฏิบัติซึ่งคุณไม่สามารถพูดถึงมาตรฐานได้แม้ว่าในทางทฤษฎีแล้วจะมี RFC
CodesInChaos

1
ชื่อนามสกุลไฟล์ CSV ควรได้รับการเปลี่ยนเป็น DSV - ไฟล์คั่นค่าตัวคั่น
Ambuj

สำหรับคำตอบทั้งหมดที่แยกสตริงกับอักขระตัวคั่นนี่ไม่ใช่วิธีที่ดีที่สุด มีกฎเพิ่มเติมสำหรับรูปแบบ CSV ที่สิ่งนี้จะไม่ครอบคลุม เป็นการดีที่สุดที่จะใช้เครื่องมือแยกวิเคราะห์บุคคลที่สาม ข้อมูลเพิ่มเติม
iliketocode

คำตอบ:


415

คุณสามารถทำได้เช่นนี้:

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
ขอบคุณสำหรับการนี้ผมลืมวิธีการสายแยกในไฟล์ CSV (ฉันโง่!) แต่วิธีการแก้ปัญหาของคุณช่วยให้ฉัน :)
Hallaghan

4
มากกว่า 3 ปีต่อมาและคำถามนี้ยังคงช่วยเหลือใครบางคน ฉันรู้สึกแย่ที่คุณไม่ได้รับการยอมรับในเรื่องนี้
AdamMc331

12
ไม่สามารถจัดการค่าฟิลด์ด้วยเครื่องหมายจุลภาคเป็นต้น
Mike

12
ควรใช้usingประโยคที่นี่หรืออย่างน้อยที่สุดด้วยตนเองขณะที่มันเป็นทรัพยากร Close()readerIDisposible
Assaf Israel

30
สิ่งนี้จะไม่แยกวิเคราะห์ CSV ที่เขียนเช่นcolumn1;"Special ; char in string";column3- tools.ietf.org/html/rfc4180
Ole K

173

ตัวแยกวิเคราะห์ CSV ที่ฉันโปรดปรานคือตัวสร้างในไลบรารี. NET นี่คือสมบัติที่ซ่อนอยู่ภายในเนมสเปซ Microsoft.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];
 }
}

อย่าลืมเพิ่มการอ้างอิงถึง Microsoft.VisualBasic

รายละเอียดเพิ่มเติมเกี่ยวกับ parser มีให้ที่นี่: http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html


6
ฉันชอบตัวเลือกที่ดีที่สุด ฉันไม่ต้องกังวลกับตัวละครในการหลบหนีเนื่องจากคลาสเป็นตัวแยกวิเคราะห์ CSV และไม่ใช่สิ่งที่สร้างขึ้นด้วยตนเอง
Timothy Gonzalez

22
ในกรณีที่ใครก็ตามพบเจอและสงสัยว่าคุณจะต้องรวมการอ้างอิงไปยังMicrosoft.VisualBasicแอสเซมบลีเฟรมเวิร์กตามปกติแล้วจะไม่ได้รับการอ้างอิง
apokryfos

3
ฉันหวังว่าฉันจำสิ่งนี้ได้จาก VB6 วันของฉันจะช่วยให้ฉันประหยัดเวลาได้มากในช่วงหลายปีที่ผ่านมา ในขณะที่บางคนจะพูดจาโผงผางเกี่ยวกับ VB ฉันไม่มีปัญหาเพิ่ม dll & namespace ในรหัสของฉันถ้ามันมีค่า สิ่งนี้มีค่ามาก
วอลเตอร์

2
วิธีนี้เป็น homerun โปรแกรมแยกวิเคราะห์ที่น่าเชื่อถือมากจากประสบการณ์ของฉัน
Glenn Ferrie

3
ทำไมเฉพาะใน VB dll?
Mark Choi

75

วิธี LINQ:

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

ผิดพลาด - แก้ไขโดย Nick

ดูเหมือนว่าผู้ตอบแบบดั้งเดิมพยายามเติมข้อมูลcsvด้วยอาร์เรย์ 2 มิติ - อาร์เรย์ที่มีอาร์เรย์ แต่ละรายการในอาร์เรย์แรกมีอาร์เรย์ที่แสดงหมายเลขบรรทัดนั้นกับแต่ละรายการในอาร์เรย์ที่ซ้อนกันที่มีข้อมูลสำหรับคอลัมน์นั้น ๆ

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

2
บางทีฉันอาจขาดอะไรบางอย่างไป แต่ฉันไม่แน่ใจว่าจุดของตัวแปร csv ของคุณคืออะไรคุณไม่ใช่แค่สร้างโครงสร้างข้อมูลเดียวกับที่อยู่ในบรรทัดอีกครั้ง
Ben Hughes

13
@ClayShannon .NET 1.1? ฉัน ... เสียใจมากสำหรับคุณ
contactmatt

5
@contactmatt: ฉันจะไม่ปฏิเสธคุณเกี่ยวกับความเชื่อมั่นนั้น
B. Clay Shannon

9
ฉันต้องการชี้ให้เห็นว่า csv สามารถอ้างอิงได้ ... ดังนั้นการใช้ string.Split ไม่ใช่ตัวเลือกที่ใช้งานได้
Alxandr

5
ฉันได้รับ: 'System.Array' ไม่มีคำจำกัดความสำหรับ 'แยก' และไม่มีวิธีส่วนขยาย 'แยก' ที่ยอมรับอาร์กิวเมนต์แรกของประเภท 'System.Array' ที่สามารถพบได้ (คุณหายไปโดยใช้คำสั่งหรือการอ้างอิงประกอบ ?)
Kala J

36

คุณไม่สามารถสร้างอาร์เรย์ได้ทันทีเนื่องจากคุณจำเป็นต้องทราบจำนวนแถวตั้งแต่ต้น (และสิ่งนี้จะต้องอ่านไฟล์ csv สองครั้ง)

คุณสามารถเก็บค่าในสอง List<T>และจากนั้นใช้พวกเขาหรือแปลงเป็นอาร์เรย์โดยใช้List<T>.ToArray()

ตัวอย่างที่ง่ายมาก:

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

NB

โปรดทราบว่านี่เป็นเพียงตัวอย่างง่ายๆ การใช้string.Splitไม่ได้คำนึงถึงกรณีที่บางระเบียนมีตัวคั่น;อยู่ภายใน
สำหรับวิธีที่ปลอดภัยกว่าให้ลองใช้ไลบรารีเฉพาะ csv เช่น CsvHelper บน nuget


ไม่บัญชีสำหรับการเป็นส่วนหนึ่งของค่าตัวอย่างเช่น; "value with ; inside it"ค่า CSV Surround ที่มีอักขระพิเศษพร้อมด้วยเครื่องหมายคำพูดคู่เพื่อบอกว่าเป็นสตริงตัวอักษร
ChickenFeet

1
@ChickenFeet: แน่ใจว่าเหตุผลของคำบรรยาย: "ตัวอย่างที่ง่ายมาก" อย่างไรก็ตามฉันสามารถเพิ่มบันทึกเกี่ยวกับสิ่งนั้น;)
digEmAll

ไม่ต้องกังวลผมสังเกตเห็นจำนวนมากของคำตอบอื่น ๆ ที่นี่ยังไม่บัญชีสำหรับมัน :)
ChickenFeet

1
Regex.Split (sr.ReadLine (), ", (? = (?: [^ \"] * \ "[^ \"] * \ ") * [^ \"] * $) "); // พบ เกี่ยวกับเรื่องนี้ดังนั้น ... เร็วกว่าห้องสมุด.
หยิก

34

เพิ่งเจอห้องสมุดนี้: https://github.com/JoshClose/CsvHelper

ใช้งานง่ายมากและใช้งานง่าย มีแพคเกจ nuget เกินไปซึ่งทำให้มีความรวดเร็วในการดำเนินการ: http://nuget.org/packages/CsvHelper/1.17.0 ดูเหมือนว่าจะได้รับการบำรุงรักษาอย่างแข็งขันซึ่งฉันชอบ

การกำหนดค่าให้ใช้เซมิโคลอนเป็นเรื่องง่าย: https://github.com/JoshClose/CsvHelper/wiki/Custom-Configurations


3
นี่คือคำตอบที่ดีที่สุด! ห้องสมุดที่แข็งแรงทนทานวางและม้วนได้ง่าย
Tyler Forsythe

3
ห้องสมุด CsvHelper นั้นยอดเยี่ยม เร็วสุดและใช้งานง่าย
Steve Parish

3
หากคุณกำลังมองหาไลบรารีที่สามารถจัดการกับทุกแง่มุมของรูปแบบ csv รวมถึงสตริงที่ยกมาให้ใช้อันนี้ ! น่ากลัว
แมตต์

ขอบคุณห้องสมุดที่ดีมากใช้งานง่ายและมีประสิทธิภาพมาก
Sebastián Guerrero

2
ประสิทธิภาพเปรียบเทียบกับMicrosoft.VisualBasic.FileIO.TextFieldParser(คำตอบของ cf. @ Habeeb) อย่างไร
bovender

33

ฉันมักจะใช้parserนี้จาก codeprojectเนื่องจากมีตัวละครมากมายที่หลบหนีและคล้ายกับที่มันจัดการกับฉัน


2
สิ่งนี้ดีมากและรวดเร็ว หากคุณอยู่ในสถานการณ์ทางธุรกิจและจำเป็นต้องใช้โปรแกรมนี้
gjvdkamp

8
เครื่องมือแยกวิเคราะห์นี้มีอยู่ในแกลเลอรี Nuget ในชื่อ LumenWorks.Framework.IO ในกรณีที่คุณไม่ต้องการลงทะเบียน CodeProject เพื่อดาวน์โหลด
Greg McCoy

30

นี่คือความหลากหลายของคำตอบที่ได้รับการโหวตสูงสุด:

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

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

คุณเข้าถึงแถวและคอลัมน์ในตัวแปร csv ได้อย่างไร
แมทธิวล็อค

1
คุณจัดการกับเครื่องหมายจุลภาคของ Escape ได้อย่างไร
Kuangwei Zhang

ไม่จัดการเครื่องหมายจุลภาคภายในคอลัมน์ ดีกว่าที่จะใช้ห้องสมุดที่มีประสิทธิภาพCsvHelperตามคำตอบ
Tim Partridge

11

หากคุณต้องการข้าม (ส่วนหัว) และ / หรือคอลัมน์คุณสามารถใช้สิ่งนี้เพื่อสร้างอาร์เรย์แบบสองมิติ:

    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

สิ่งนี้มีประโยชน์มากหากคุณต้องการกำหนดรูปร่างข้อมูลก่อนที่จะดำเนินการเพิ่มเติม (สมมติว่า 2 บรรทัดแรกประกอบด้วยบรรทัดแรกและคอลัมน์แรกเป็นชื่อแถว - ซึ่งคุณไม่จำเป็นต้องมีในอาร์เรย์เพราะคุณเพิ่ง ต้องการพิจารณาข้อมูล)

NBคุณสามารถรับหัวข้อและคอลัมน์ที่ 1 ได้ง่ายๆโดยใช้รหัสต่อไปนี้:

    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

ตัวอย่างโค้ดนี้จะถือว่าโครงสร้างของ*.csvไฟล์ของคุณต่อไปนี้:

CSV CSV

หมายเหตุ:หากคุณต้องการข้ามแถวที่ว่างเปล่าซึ่งบางครั้งสามารถทำได้โดยสะดวกคุณสามารถทำได้โดยการแทรก

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

ระหว่างfromและselectคำสั่งในตัวอย่างรหัสLINQด้านบน


10

คุณสามารถใช้ Microsoft.VisualBasic.FileIO.TextFieldParser dll ใน C # เพื่อประสิทธิภาพที่ดีขึ้น

รับตัวอย่างรหัสด้านล่างจากบทความด้านบน

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
มันไม่ได้มีประสิทธิภาพเพราะ Split ไม่ได้ทำทุกอย่างที่ TextFieldParser ทำ ตัวอย่างเช่นข้ามบรรทัดข้อคิดเห็นจัดการฟิลด์ที่ยกมาและลบ whitespace เริ่มต้น / ต่อท้าย ไม่เปรียบเทียบแบบ 1: 1 ทั้งหมด
Robert McKee

5

สวัสดีทุกคนฉันได้สร้างชั้นคงที่สำหรับการทำเช่นนี้ + ตรวจสอบคอลัมน์ + ลบเครื่องหมายโควต้า

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

ขอบคุณสำหรับความช่วยเหลือของคุณ. มันอาจช่วยแก้ปัญหาของฉันได้ จริงๆแล้วฉันต้องอ่านข้อมูลจากไฟล์แล้วจึงใส่ลงในฐานข้อมูล ในช่วงเวลาของการแทรกฉันได้รับข้อผิดพลาดข้อ จำกัด คีย์หลัก (เนื่องจากฉันมีข้อมูลในฐานข้อมูลอยู่แล้ว) ดังนั้นฉันต้องโปรแกรมเช่นนั้นมีตัวแปรอยู่แล้วอัปเดตข้อมูล
Rushabh Shah

ฉันถือว่าค่าแรกถ้า PK - คุณต้องได้รับการบันทึกโดย id จากฐานข้อมูลและถ้ามันมีอยู่กว่าปัญหาคำสั่ง UPDATE มิฉะนั้นแทรกบันทึกใหม่
Jakub Konecki

3

นี่คือกรณีพิเศษที่เขตข้อมูลหนึ่งมีเครื่องหมายอัฒภาค (";") ซึ่งเป็นส่วนหนึ่งของข้อมูลในกรณีนั้นคำตอบส่วนใหญ่จะล้มเหลว

แก้ไขมันกรณีที่จะ

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

ไลบรารีแบบเปิดแหล่งAngara.Tableอนุญาตให้โหลด CSV ลงในคอลัมน์ที่พิมพ์ดังนั้นคุณสามารถรับอาร์เรย์จากคอลัมน์ แต่ละคอลัมน์สามารถทำดัชนีได้ทั้งชื่อหรือดัชนี ดูhttp://predictionmachines.github.io/Angara.Table/saveload.html

ไลบรารีดังต่อไปนี้ RFC4180 สำหรับ CSV; มันเปิดใช้งานการอนุมานประเภทและสตริงหลายบรรทัด

ตัวอย่าง:

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

คุณสามารถดูประเภทคอลัมน์โดยใช้คอลัมน์ประเภทเช่น

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

เนื่องจากไลบรารีเน้นที่ F # คุณอาจต้องเพิ่มการอ้างอิงไปยังแอสเซมบลี FSharp.Core 4.4 คลิก 'เพิ่มการอ้างอิง' ในโครงการและเลือก FSharp.Core 4.4 ภายใต้ "Assemblies" -> "Extensions"


2

ฉันใช้เวลาสองสามชั่วโมงในการค้นหาไลบรารี่ที่ถูกต้อง แต่ในที่สุดฉันก็เขียนโค้ดของตัวเอง :) คุณสามารถอ่านไฟล์ (หรือฐานข้อมูล) ด้วยเครื่องมืออะไรก็ได้ที่คุณต้องการแล้วใช้รูทีนต่อไปนี้กับแต่ละบรรทัด:

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

ฉันใช้ 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] ...
}

1

ฉันเป็นนักเรียนที่ทำงานเกี่ยวกับวิทยานิพนธ์ของฉัน แต่นี่เป็นวิธีที่ฉันจะแก้ไขและมันก็ใช้ได้ดีสำหรับฉัน ก่อนอื่นให้คุณเลือกไฟล์จากไดเรกทอรี (เฉพาะในรูปแบบ 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
        );
    }
}

0

ยังคงผิด คุณต้องชดเชย "" ในเครื่องหมายคำพูด นี่คือโซลูชันของฉันสไตล์ Microsoft 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;
    }
}

3
มันไม่ได้จัดการกับกรณีเมื่อมีการขึ้นบรรทัดใหม่ภายในค่าของคอลัมน์;)
Emil

0

ฉันมีห้องสมุดที่ทำทุกอย่างที่คุณต้องการ

เมื่อไม่นานมานี้ฉันได้เขียนไลบรารีที่ง่ายและเร็วพอสำหรับการทำงานกับไฟล์ CSV คุณสามารถค้นหาได้จากลิงค์ต่อไปนี้: https://github.com/ukushu/DataExporter

มันทำงานได้กับ CSV เช่นเดียวกับอาร์เรย์ 2 มิติ เหมือนที่คุณต้องการ

ตัวอย่างเช่นในกรณีที่คุณต้องการค่าทั้งหมดของแถวที่ 3 คุณจำเป็นต้องเขียนเท่านั้น:

Csv csv = new Csv();

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

var allValuesOf3rdRow = csv.Rows[2];

หรือเพื่ออ่านเซลล์ที่สองของ

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

-1

ดูนี่สิ

ใช้ CsvFramework

ใช้ System.Collections.Generic;

เนมสเปซ 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>();


    }
}

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.