通过C#中的csv文件读取

时间:2012-07-25 18:25:45

标签: c# csv datatable

我正在使用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());
        }
    }
}

5 个答案:

答案 0 :(得分:0)

我在这里有一些代码可以帮到你:

  

Reading CSV files in C#

在我的回答中使用该类,您的新代码看起来非常接近:

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方法。并且关闭另一个问题:是的,这将读取文件两次。如果这个确实成为性能问题,你可以编写代码,这样它只会读取一次,但它看起来会更像你上面的内容。可能性是,较短代码的维护优势超过了此处的性能问题。

答案 1 :(得分:0)

是的,有另一种方法,而不是使用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;
        }

答案 2 :(得分:0)

我最近遇到过这个问题。不是使用Microsoft.Jet.OleDb.4.0,而是依赖于需要x86,但我的应用程序的许多部分需要在x64中运行。我通过做两件事来解决它:

  1. 将x86依赖项分离到自己的项目中。我将该项目的目标更改为x86(并将所有其他项目目标保留为AnyCPU - 我的应用程序部署到64位服务器)

  2. 我在GAC中重新注册了x86依赖项。仍然不确定为什么这会产生很大的不同,但在这样做之后,它起作用了。

  3. 我的猜测是这个问题需要类似的方法。这个链接对我有所帮助:https://lostechies.com/gabrielschenker/2009/10/21/force-net-application-to-run-in-32bit-process-on-64bit-os/

    我探索过的一种激进的方法,但最终没有使用的是将x86代码包装在其自身的可执行文件中,该输出将输出写入控制台并使用Process.Start()和{{1}虽然我不建议这样做。虽然是一个有趣的实验。

答案 3 :(得分:-1)

如果你不想强烈输入,你可以依靠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;
        }

答案 4 :(得分:-1)

尝试编译为32位应用程序(平台目标:构建选项中的x86)。