簡體   English   中英

通過C#讀取CSV文件

[英]Reading through a csv file in C#

我正在使用Microsoft.Jet.OleDb.4.0來讀取csv文件。 我比較內部信息,如果滿足某些條件,則將其添加到下拉列表中。 我的問題是Microsoft.Jet.OleDb.4.0僅與x86兼容。 但是,我還有其他功能需要作為x64運行。 是否有更新或替代方法?

下面是我的代碼。 如果我在x86中,當前可以使用。

DataTable dataTable = new DataTable("table1");
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + Directory.GetCurrentDirectory() + "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\""))
{
    conn.Open();
    string strQuery = "SELECT * FROM [" + "report.csv" + "]";
    OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn);
    adapter.Fill(dataTable);
    foreach (DataRow rows in dataTable.Rows) {
        if (rows[1].ToString() == "False")
        {
            unlicensed.Items.Add(rows[0].ToString());
        }
        if (rows[2].ToString() == "False")
        {
            litigation.Items.Add(rows[0].ToString());
        }
    }
}

我在這里的另一個問題中有一些代碼可以幫助您:

在C#中讀取CSV文件

使用我的答案中的類,您的新代碼將非常接近此代碼:

unlicensed.DataSource = CSV.FromFile("report.csv")
                     .Where(r => r[1] != "False").Select(r => r[0]);
litigation.DataSource = CSV.FromFile("report.csv")
                     .Where(r => r[2] != "False").Select(r => r[0]);

聽起來您的“錯誤”條件可能有所不同,但這將非常接近結果。 您可能還希望對列表使用Append方法。 而要回答另一個問題:是的,這將讀取文件兩次。 如果這確實成為性能問題,則可以編寫代碼,使其僅讀取一次,但是它看起來更像上面的內容。 奇怪的是,較短代碼的維護優勢超過了此處的性能問題。

是的,還有一種替代方法,可以使用以下方法來代替使用Microsoft.Jet.OleDb.4.0。

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

我最近有這個問題。 不是使用Microsoft.Jet.OleDb.4.0,而是需要x86的依賴項,但我的應用程序的許多部分都需要在x64中運行。 我通過做兩件事解決了它:

  1. 將x86依賴項分離到自己的項目中。 我將該項目的目標更改為x86(並將其他所有項目目標保留為AnyCPU-我的應用程序已部署到64位服務器)

  2. 我在GAC中重新注冊了x86依賴項。 仍然不確定為什么這樣做有很大的不同,但是這樣做之后,它仍然有效。

我的猜測是,此問題將需要類似的方法。 該鏈接對我有很大幫助: https : //lostechies.com/gabrielschenker/2009/10/21/force-net-application-to-run-in-32bit-process-on-64bit-os/


我探索,工作但最終未能實現的一種根本方法是將x86代碼包裝在其自己的可執行文件中,該可執行文件將輸出寫入控制台,並使用Process.Start()ProcessStartInfo.RedirectStandardOutput盡管我不建議這樣做。 雖然是一個有趣的實驗。

如果您不想被強類型化,則可以依靠List

        public List<List<string>> ReadCsvTable(string path) {
            List<List<string>> table = new List<List<string>>();
            string[] lines = System.IO.File.ReadAllLines(path);
            foreach (string line in lines) {
                table.Add(new List<string>(line.Split(',')));
            }
            return table;
        }

如果您想特別注意下面的用戶突出顯示的問題,則應該處理引用的字段,我希望:

        public List<List<string>> ReadCsvTable(string path) {
            List<List<string>> table = new List<List<string>>();
            string[] lines = System.IO.File.ReadAllLines(path);
            foreach (string line in lines) {
                List<string> rawFields = new List<string>(line.Split(','));                
                List<string> processedFields = new List<string>();
                foreach(string field in rawFields){
                    Match m = Regex.Match("^\"?(^<value>.*)\"?$", line);
                    processedFields.Add(m.Groups["value"].Value);
                }                
                table.Add(processedFields);
            }
            return table;
        }

嘗試編譯為32位應用程序(平台目標:構建選項中為x86)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM