[英]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());
}
}
}
我在這里的另一個問題中有一些代碼可以幫助您:
使用我的答案中的類,您的新代碼將非常接近此代碼:
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中運行。 我通過做兩件事解決了它:
將x86依賴項分離到自己的項目中。 我將該項目的目標更改為x86(並將其他所有項目目標保留為AnyCPU-我的應用程序已部署到64位服務器)
我在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.