繁体   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