DBF-файлы весьма распространены в государственном секторе. Их активно используют для переноса данных из одной базы данных в другую. Все, казалось бы, хорошо, но есть один неприятный момент. Какой? Кодировка!
Как часто приходится ломать голову из-за этих кодировок. Но ничего не поделаешь, приходится с этой неприятностью как-то справляться. Итак, что же нам делать, если мы делаем свое приложение, для работы с dbf файлом и возникли трудности с кодировкой?
В dbf файле за кодовую страницу отвечает 29-й байт. Например, значение 101 означает кодовую страницу DOS-866, 201 - Windows-1251, а значение 0 указывает, что нужно использовать системные настройки. Зная это, можно умело манипулировать кодировкой при импорте и экспорте dbf. Выставить нужную кодировку при создании файла или если кодировка содержимого не соответствует кодировке кодовой страницы, то мы легко можем менять последнюю путем записи нужного числа в 29 байт. Приведенный ниже код это демонстрирует.
FileStream fs = new FileStream(path, FileMode.Open);
fs.Seek(29, SeekOrigin.Begin);
fs.WriteByte(201);
fs.Close();
Примерно таким образом мы можем и считать байт и привести его к числу, для удобства, чтобы знать, какая кодовая страница у файла.
Все, казалось бы, хорошо, вот только при подключении через Microsoft Jet Database Engine, упорно игнорируется кодовая страница. Кодировка берется из реестра, параметр DataCodePage. Найти этот параметр можно в следующих ветках реестра:
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.0\Engines\Xbase'
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5\Engines\Xbase'
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Xbase'
Если при чтении dbf мы можем конвертировать данные непосредственно в нашем приложении, то при экспорте без манипуляции со значением параметра DataCodePage никак не обойтись. По сути нам надо запомнить, что при значении "OEM" работа проходит при DOS кодировке, а при значении "ANSI" - в Windows. Если всегда экспорт должен проходить в одной кодировке, то можно сразу один раз ее выставить и забыть. Иначе нам придется перед каждой операцией менять значение реестра. Но таким образом наши пользователи всегда будут получать данные в понятном и нужном им виде.