简体   繁体   English

通过C#读取CSV文件

[英]Reading through a csv file in C#

I am using Microsoft.Jet.OleDb.4.0 to read through a csv file. 我正在使用Microsoft.Jet.OleDb.4.0来读取csv文件。 I compare the information inside and if it meets certain criteria add it to a dropdown. 我比较内部信息,如果满足某些条件,则将其添加到下拉列表中。 My problem is that Microsoft.Jet.OleDb.4.0 is only compatible with x86. 我的问题是Microsoft.Jet.OleDb.4.0仅与x86兼容。 However, I have other functions that need to run as x64. 但是,我还有其他功能需要作为x64运行。 Is there an update or an alternative to do this? 是否有更新或替代方法?

below is my code. 下面是我的代码。 Which currently works if I am in x86. 如果我在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());
        }
    }
}

I have some code in another question here that may help you: 我在这里的另一个问题中有一些代码可以帮助您:

Reading CSV files in C# 在C#中读取CSV文件

Using the class in my answer, your new code would look very close to this: 使用我的答案中的类,您的新代码将非常接近此代码:

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

It sounds like your "False" criteria may be a little different, but that's going to be pretty close to the result. 听起来您的“错误”条件可能有所不同,但这将非常接近结果。 You may also want to use an Append method with your list. 您可能还希望对列表使用Append方法。 And to head off the other question: yes, this will read the file twice. 而要回答另一个问题:是的,这将读取文件两次。 If this really becomes a performance issue, you could write code so it only reads it once, but it would look a lot more like what you have above. 如果这确实成为性能问题,则可以编写代码,使其仅读取一次,但是它看起来更像上面的内容。 Odds are, the maintenance benefit of the shorter code outweighs the performance issue here. 奇怪的是,较短代码的维护优势超过了此处的性能问题。

Yes, there is an alternative way, instead of using Microsoft.Jet.OleDb.4.0 you can use below method.. 是的,还有一种替代方法,可以使用以下方法来代替使用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;
        }

I had this issue recently. 我最近有这个问题。 Not with Microsoft.Jet.OleDb.4.0, but with a dependency that requied x86 but many parts of my app needed to be run in x64. 不是使用Microsoft.Jet.OleDb.4.0,而是需要x86的依赖项,但我的应用程序的许多部分都需要在x64中运行。 I solved it by doing 2 things: 我通过做两件事解决了它:

  1. Separating that x86 dependency into its own project. 将x86依赖项分离到自己的项目中。 I changed the target of that one project to x86 (and left every other project target as AnyCPU - my app being deployed to a 64-bit server) 我将该项目的目标更改为x86(并将其他所有项目目标保留为AnyCPU-我的应用程序已部署到64位服务器)

  2. I reregistered the x86 dependency in the GAC. 我在GAC中重新注册了x86依赖项。 Still not sure why that made a big difference though, but after doing so, it worked. 仍然不确定为什么这样做有很大的不同,但是这样做之后,它仍然有效。

My guess is that this issue would require a similar approach. 我的猜测是,此问题将需要类似的方法。 This link helped me quite a bit: https://lostechies.com/gabrielschenker/2009/10/21/force-net-application-to-run-in-32bit-process-on-64bit-os/ 该链接对我有很大帮助: https : //lostechies.com/gabrielschenker/2009/10/21/force-net-application-to-run-in-32bit-process-on-64bit-os/


A radical approach which I explored, worked, but ended up not going with was wrapping the x86 code in it's own executable that writes the output to the console and using Process.Start() and ProcessStartInfo.RedirectStandardOutput though I don't recommend doing that. 我探索,工作但最终未能实现的一种根本方法是将x86代码包装在其自己的可执行文件中,该可执行文件将输出写入控制台,并使用Process.Start()ProcessStartInfo.RedirectStandardOutput尽管我不建议这样做。 Was a fun experiment though. 虽然是一个有趣的实验。

if you don't want to be Strongly Typed you can just rely on List 如果您不想被强类型化,则可以依靠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;
        }

and if you want to pay much attention to the problem highlighted by a user below this should handle quoted fields I hope: 如果您想特别注意下面的用户突出显示的问题,则应该处理引用的字段,我希望:

        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