如何用C#以最简方式读取dbase4编码文件?OleDB方案报错
C#读取西门子840D powerline导出的dBase IV文件的最简方案
问题背景
- 从西门子CNC控制系统840D powerline导出的机床数据为dBase IV格式,直接读取仅能识别ASCII字符,非ASCII特殊字符无法正常解析
- 尝试使用OleDB方案读取时触发平台不支持异常,错误信息如下:
OdebD Error System.TypeInitializationException: The type initializer for 'System.Data.OleDb.OleDbConnection' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.Data.OleDb.OleDbConnectionFactory' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.Data.ProviderBase.DbConnectionPoolCountersNoCounters' threw an exception. ---> System.TypeInitializationException: The type initializer for 'CreationData' threw an exception. ---> System.PlatformNotSupportedException: Performance Counters are not supported on this platform. at System.Diagnostics.CounterCreationData..ctor(String counterName, String counterHelp, PerformanceCounterType counterType) at System.Data.ProviderBase.DbConnectionPoolCounters.CreationData..cctor() --- End of inner exception stack trace --- at System.Data.ProviderBase.DbConnectionPoolCounters..ctor(String categoryName, String categoryHelp) at System.Data.ProviderBase.DbConnectionPoolCounters..ctor() at System.Data.ProviderBase.DbConnectionPoolCountersNoCounters..ctor() at System.Data.ProviderBase.DbConnectionPoolCountersNoCounters..cctor() --- End of inner exception stack trace --- at System.Data.ProviderBase.DbConnectionFactory..ctor() at System.Data.OleDb.OleDbConnectionFactory..ctor() at System.Data.OleDb.OleDbConnectionFactory..cctor() --- End of inner exception stack trace --- at System.Data.OleDb.OleDbConnection..cctor() --- End of inner exception stack trace --- at System.Data.OleDb.OleDbConnection.get_ConnectionFactory() at System.Data.OleDb.OleDbConnection.ConnectionString_Set(DbConnectionPoolKey key) at System.Data.OleDb.OleDbConnection.ConnectionString_Set(String value) at System.Data.OleDb.OleDbConnection.set_ConnectionString(String value) at System.Data.OleDb.OleDbConnection..ctor(String connectionString) at WebApplication7.Pages.PLC_Var.dbase() in C:\01_md9bu_Projects\ASP\WebApplication7\Pages\PLC_Var.razor.cs:line 37010/1/2022 1:57:22 PM
- 原尝试的OleDB代码:
public void dbase() { try { string constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test;Extended Properties=dBASE IV;User ID=Admin;Password=;"; using (OleDbConnection con = new OleDbConnection(constr)) { var sql = "select * from " + "NC_MD_ACC"; OleDbCommand cmd = new OleDbCommand(sql, con); con.Open(); DataSet ds = new DataSet(); ; OleDbDataAdapter da = new OleDbDataAdapter(cmd); da.Fill(ds); Deltalogic.NC_VAR_test_string = ds.Tables[0].ToString(); using (StreamWriter sw = File.AppendText(CommonClass.error_path)) { sw.WriteLine("OdebD OK " + Convert.ToString(DateTime.Now)); } } } catch (Exception e) { using (StreamWriter sw = File.AppendText(CommonClass.error_path)) { sw.WriteLine("OdebD Error " + e + Convert.ToString(DateTime.Now)); } } }
最简可行方案:使用DbfDataReader库
OleDB方案失败的原因是Microsoft.Jet.OLEDB.4.0是老旧的Windows专属驱动,在.NET Core/.NET 5+等现代平台中不支持性能计数器,导致初始化异常。推荐使用专门的dBase文件读取库DbfDataReader,它跨平台、轻量且支持指定编码解决特殊字符问题。
步骤1:安装NuGet包
在项目中安装DbfDataReader:
Install-Package DbfDataReader # 或者使用.NET CLI dotnet add package DbfDataReader
步骤2:编写读取代码
西门子840D导出的dBase IV文件通常使用OEM编码(如CP850),需指定对应编码以正确解析特殊字符:
using DbfDataReader; using System.Text; using System.Linq; public void ReadDbaseFile() { try { // 指定dBase文件路径 var dbfPath = @"C:\test\NC_MD_ACC.dbf"; // 西门子常用编码为CP850,可根据实际情况调整 var encoding = Encoding.GetEncoding(850); using (var dbfReader = new DbfReader(dbfPath, encoding)) { // 获取所有列名 var columns = dbfReader.Columns.Select(c => c.Name).ToList(); // 逐行读取数据 while (dbfReader.Read()) { // 拼接当前行的字段信息 var rowContent = string.Join(", ", columns.Select(col => $"{col}: {dbfReader[col]}")); Deltalogic.NC_VAR_test_string += rowContent + Environment.NewLine; } } using (StreamWriter sw = File.AppendText(CommonClass.error_path)) { sw.WriteLine("DbfDataReader OK " + DateTime.Now.ToString()); } } catch (Exception e) { using (StreamWriter sw = File.AppendText(CommonClass.error_path)) { sw.WriteLine("DbfDataReader Error " + e + " " + DateTime.Now.ToString()); } } }
关键说明
- 编码选择:如果CP850无法正确解析,可尝试
Encoding.GetEncoding(1252)(Windows-1252)或西门子机床对应的其他OEM编码 - 该库支持dBase IV、dBase III等多种格式,无需依赖OleDB驱动,兼容.NET Framework/.NET Core/.NET 5+所有平台
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

