2010-10-02 122 views
0

我正在使用C#和.NET 3.5,嘗試使用Microsoft dBase Driver使用ODBC從舊的dbf文件導入某些數據。在不同的計算機上使用dBase III .dbf文件進行編碼

dbf採用dBase III格式,並使用ibm850編碼字符串。

現在,當我在我的機器上運行我的程序時,從OdbcDataReader讀取的所有字符串數據都會轉換爲UTF-16或UTF-8或idk,並將其另存爲UTF-8並且一切正常。當我嘗試在XP中使用此程序時,某些字符未正確轉換爲UTF-8。例如,'Õ'。也可能有其他一些。 'Ä','Ö'和'Ü'等字符都可以。這就是問題。 也許ODBC或驅動程序使用一些機器文化信息或東西搞砸了一切。

是否有可能從數據庫讀取字符串爲二進制?也許有些功能像CONVERT或CAST?或者我可以在哪裏找到適用於這個dBase驅動程序或其他驅動程序的SQL函數和語法的一些參考?我四處搜尋,找不到任何東西。使用ODBC和SQL時我感到非常盲目。

現在我正在使用一個臨時黑客來代替所有σ與Õ的。

謝謝!

示例代碼:

System.Data.Odbc.OdbcConnection oConn = new System.Data.Odbc.OdbcConnection(); 
oConn.ConnectionString = @"Driver={Microsoft dBase Driver (*.dbf)};DriverID=277;Dbq=" + dbPath + ";"; 
oConn.Open(); 

System.Data.Odbc.OdbcCommand oCmd = oConn.CreateCommand(); 
oCmd.CommandText = @"SELECT name FROM " + dbPath + "TABLE.DBF"; 

System.Data.Odbc.OdbcDataReader reader = oCmd.ExecuteReader(); 
reader.Read(); 

byte[] buf = Encoding.UTF8.GetBytes(reader.GetString(0)); 
BinaryWriter writer = new BinaryWriter(File.Open(@"C:\DBF\Test.txt", FileMode.Create)); 
writer.Write(buf); 

結果:

E5在DBF(O,以850)

Test.txt的上PC1:C3 95(O,以UTF-8)

pc2上的Test.txt:CF 83(UTF-8中的σ)

回答

2

如果您仍然遇到這些文件的問題,我可以幫助您。

什麼是在文件中的偏移量29(十進制)「代碼頁字節」又名「語言驅動程序ID」(LDID)?

我有一個基於Python的DBF閱讀器,它可以讀取任何字段數據類型和幾乎任何代碼頁 - 它有從代碼頁字節到代碼頁號的各種映射源編譯的長列表。選項是(1)相信LDID,傳遞Unicode(2)忽略LDID,傳遞未解碼的字節(3)覆蓋LDID,用特定的代碼頁解碼爲Unicode。當然,Unicode可以編碼爲UTF-8。

DBF閱讀器也做了很多合理性交叉檢查,這可能有助於調查爲什麼VFP認爲文件已損壞。

您怎麼知道它使用IBM850?我擁有的另一塊Python代碼是一個原型編碼檢測器,它與來自Mozilla代碼的'chardet'這樣的檢測器不是以網絡爲中心的,並且可以愉快地識別大多數舊的DOS代碼頁 - 這可能會有所幫助。

一個觀察:希臘字母小寫sigma(σ)在代碼頁437中是0xE5,代碼頁850 - 「pc2」似乎有點過時了......

如果你認爲我可以幫上什麼忙,隨時insert_punctuation發郵件給我(「sjmachin」,「詞典」,「淨」)

+0

嗨,即時通訊也有閱讀一個Dbase文件的問題,在我的瑞典語Windows客戶端閱讀時工作正常,但在英語操作系統上運行時會混淆字符,你還在提供幫助嗎? – Andreas 2011-08-25 06:45:04

+0

@Andreas:給我發電子郵件。什麼是文件的LDID?你在讀什麼? 「搞砸人物」並沒有幫助。顯示repr(預期字符),repr(實際字符)。如果可能,請將您的代碼和文件發送給我。 – 2011-08-25 08:29:40

+0

我在詞彙點網向您發送了一封電子郵件sjmachin – Andreas 2011-08-25 13:47:49

0

您是否嘗試過使用Visual Foxpro驅動程序「V FPOleDb「驅動程序,而不是?

+0

是的,我有。 Foxpro驅動程序不喜歡我的數據庫 - 告訴我它已損壞,但是當我在十六進制編輯器中打開該文件並將其與文件格式規格進行比較時,一切都很正常。 – Ivarpoiss 2010-10-04 16:38:45

1

試試這個代碼。

var oConn = new System.Data.Odbc.OdbcConnection(); 
oConn.ConnectionString = "Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=" + dbPath; 
oConn.Open(); 
var oCmd = oConn.CreateCommand(); 
oCmd.CommandText = @"SELECT name FROM " + dbPath + "TABLE.DBF"; 
var reader = oCmd.ExecuteReader(); 
reader.Read(); 
byte[] A = Encoding.GetEncoding(Encoding.Default.CodePage).GetBytes(reader.GetString(0)); 
string p = Encoding.Unicode.GetString((Encoding.Convert(Encoding.GetEncoding(850), Encoding.Unicode, A))); 
1

當你讀DBF文件,你應該明白,你應該考慮3種編碼:

1.Encoding在數據庫提供商讀取文件。它取決於 供應商和當前的操作系統。這種編碼應該用於字節數組接收。例如我的PC上:

  • 當我使用連接字符串「數據源= {0}; 提供商= Microsoft.JET.OLEDB.4.0;擴展屬性=質數據庫IV;用戶 ID =;密碼= ; 「字符串都使用866代碼頁(俄文 MS-DOS)

  • 讀當我使用連接字符串」 數據源= {0}; 提供商= vfpoledb.1;獨佔=無;整理順序=機器「,字符串 使用編碼讀取。默認(1251編碼頁)

2.將字符串寫入dbf文件的編碼。它可以從29字節的dbf文件中收到,但實際上無論如何標記dbf文件編碼,只需知道使用了什麼編碼。這個編碼將被用作字符串轉換期間的源編碼。

3.編碼字符串應該被轉換。這通常是UTF-8。

所以字符串轉換應該是這樣的:

byte[] bytes = Encoding.GetEncoding(codePage1).GetBytes(reader.GetString(0)); 

string result = Encoding.UTF8.GetString((Encoding.Convert(Encoding.GetEncoding(codePage2), Encoding.UTF8, bytes))); 
相關問題