При попытке прочитать файл .dbf с помощью Панель управления -> Регион -> Административный -> Регион настройки = "Engli sh (Великобритания)" * системные настройки, русские символы читаются в неизвестная кодировка. Но если эта опция включена Region Settings = "Russian (Russia)" , то символы читаются правильно. Я попробовал следующие варианты:
- Изменены параметры подключения с
private constant string SOURCE_CONNECTION_STRING = "Provider = Microsoft.Jet.OLEDB.4.0; Advanced properties = dBASE; Data source = {0};";
до private constant string SOURCE_CONNECTION_STRING = "Provider = Microsoft.Jet.OLEDB.4.0; Advanced properties = 'dBASE IV; character set = 1251; HDR = Yes; FMT = delimited"; Data Source = {0}; ";
, но это не помогло. Использовать метод решения:
private string Decode(string input)
{
Encoding fromEncoding = Encoding.GetEncoding("cp850");
Encoding toEncoding = Encoding.GetEncoding(866);
string returnValue = toEncoding.GetString(fromEncoding.GetBytes(input));
return returnValue;
}
Метод 2, использующий явное декодирование, помог мне. Я хотел бы знать, могу ли я каким-то образом установить кодировку, которую я ожидаю, явно в настройках класса "OleDbConnection" или каким-либо другим способом?
- Вот пример полученной строки из файла .dbf - ÔóÔ «¡« ¼¡Ù® «¬ÓÒú.
- Файл DBF
Пример класса:
class DbfReader
{
private const string COUNT_ATTRIBUTE_NAME = "count";
private const string ROW_ELEMENT_NAME = "r";
private const string MappedTableName = "SOCRBASE";
private const string SOURCE_CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Extended Properties='dBASE IV;characterset=1251;HDR=Yes;FMT=Delimited'; " +
"Data Source={0};";
private static readonly string TableName = "socrbase";
private static readonly string GetCountQuery = $"select count(1) from [{TableName}]";
private static readonly List<string> Columns = new List<string> { "level", "scname", "socrname", "kod_t_st" };
private static string SelectQuery => $"select [level], [scname], [socrname], [kod_t_st] from [{TableName}]";
public void Convert(string dataSourceFolder)
{
using (var srcConn = new OleDbConnection(string.Format(SOURCE_CONNECTION_STRING, dataSourceFolder)))
{
srcConn.Open();
Exception exception = null;
try
{
var xmlFilePath = GetTableFileName(dataSourceFolder, TableName);
Directory.CreateDirectory(Path.GetDirectoryName(xmlFilePath));
var xml = new XmlTextWriter(xmlFilePath, Encoding.UTF8);
xml.WriteStartDocument();
var reader = new OleDbCommand(SelectQuery, srcConn).ExecuteReader();
xml.WriteStartElement(MappedTableName);
xml.WriteAttributeString(COUNT_ATTRIBUTE_NAME, ((int)new OleDbCommand(GetCountQuery, srcConn).ExecuteScalar()).ToString());
while (reader.Read())
{
xml.WriteStartElement(ROW_ELEMENT_NAME);
foreach (var column in Columns)
{
xml.WriteStartElement(column);
var value = reader[column].ToString();
var decodeValue = Decode(value);
xml.WriteCData(value);
xml.WriteEndElement();
}
xml.WriteEndElement();
}
xml.WriteEndElement();
xml.WriteEndDocument();
xml.Close();
Console.WriteLine("XML has been created");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
private string Decode(string input)
{
Encoding fromEncoding = Encoding.GetEncoding("cp850");
Encoding toEncoding = Encoding.GetEncoding(866);
string returnValue = toEncoding.GetString(fromEncoding.GetBytes(input));
return returnValue;
}
private string GetTableFileName(string dataSourceFolder, string tableName)
{
return Path.Combine(dataSourceFolder, "xml", $"{tableName}.xml");
}
}