Чтение из .dbf с заданной кодировкой

155
14 марта 2022, 03:10

При попытке считать.dbf файл с настройкой системы Control Panel -> Region -> Administrative -> Region Settings = "English (UK)" русские символы считываются в не известной кодировке. Но если данную опцию переключить Region Settings = "Russian (Russia)", то символы считываюся корректно. Варианты, которые я попробовал:

  1. Изменять строку подключения с private const string SOURCE_CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=dBASE; Data Source={0};"; на 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};";, но это не помогло.
  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;
    }
    
  3. Использование FoxPro (но данный вариант мне не подходит)

Мне помог вариант - 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 static string TableName = "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 string GetCountQuery = $"select count(1) from [{TableName}]";
        private static string SelectQuery => $"select [{"level"}], [{"scname"}], [{"socrname"}], [{"kod_t_st"}] from [{TableName}]";
        private static List<string> Columns = new List<string> { "level", "scname", "socrname", "kod_t_st" };

        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();
                            xml.WriteCData(value);
                            xml.WriteEndElement();
                        }
                        xml.WriteEndElement();
                    }
                    xml.WriteEndElement();
                    xml.WriteEndDocument();
                    xml.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }
        private string GetTableFileName(string dataSourceFolder, string tableName)
        {
            return Path.Combine(dataSourceFolder, "xml", $"{tableName}.xml");
        }
    }
READ ALSO
Как реализовать правильный обход по матрице?

Как реализовать правильный обход по матрице?

Дело такое, что на учебе было дано заданиеЗадача кажется не из простых и до решения до сего момента не могу прийти

111
Как работают виртуальные функции в c#?

Как работают виртуальные функции в c#?

Есть ли вообще понятие таблицы виртуальных функций в шарпе? Допустим есть иерархия классов, в классе на вершине иерархии виртуальный метод,...

244
С# проверка параметров

С# проверка параметров

ПомогитеКак сделать проверку, передается ли в метод хоть какое то числовое значение?

80