Чтение из .dbf с помощью dBASE IV - PullRequest
1 голос
/ 27 января 2020

При попытке прочитать файл .dbf с помощью Панель управления -> Регион -> Административный -> Регион настройки = "Engli sh (Великобритания)" * системные настройки, русские символы читаются в неизвестная кодировка. Но если эта опция включена Region Settings = "Russian (Russia)" , то символы читаются правильно. Я попробовал следующие варианты:

  1. Изменены параметры подключения с 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}; ";, но это не помогло.
  2. Использовать метод решения:

    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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...