Как я могу прочитать файл DBF с неправильно определенными типами данных столбцов, используя ADO.NET? - PullRequest
2 голосов
/ 18 мая 2010

У меня есть несколько файлов DBF, сгенерированных третьей стороной, которые мне нужно иметь возможность запрашивать. У меня возникли проблемы, потому что все типы столбцов были определены как символы, но данные в некоторых из этих полей на самом деле содержат двоичные данные. Если я пытаюсь прочитать эти поля, используя OleDbDataReader как что-либо кроме массива строк или символов, я получаю исключение InvalidCastException, но мне нужно иметь возможность читать их как двоичное значение или, по крайней мере, приводить / преобразовывать их после того, как они прочитаны , Столбцы, которые на самом деле содержат текст, возвращаются, как и ожидалось.

Например, самый первый столбец определяется как символьное поле длиной 2 байта, но поле содержит 16-разрядное целое число.

Я написал следующий тестовый код, чтобы прочитать первый столбец и преобразовать его в соответствующий тип данных, но значение получается неверным.

Первая строка базы данных имеет значение 17365 (0x43D5) в первом столбце. Запустив следующий код, я получу 17215 (0x433F). Я почти уверен, что это связано с использованием кодировки ASCII для получения байтов из строки, возвращаемой считывателем данных, но я не уверен в другом способе получения значения в нужном мне формате, кроме написать свой собственный читатель DBF и вообще обойти ADO.NET, что я не хочу делать, если я абсолютно не обязан. Любая помощь будет принята с благодарностью.

        byte[] c0;
        int i0; 

        string con = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\ASTM;Extended Properties=dBASE III;User ID=Admin;Password=;";

        using (OleDbConnection c = new OleDbConnection(con))
        {
            c.Open();
            OleDbCommand cmd = c.CreateCommand();
            cmd.CommandText = "SELECT * FROM astm2007";
            OleDbDataReader dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                c0 = Encoding.ASCII.GetBytes(dr.GetValue(0).ToString());

                i0 = BitConverter.ToInt16(c0, 0);
            }
            dr.Dispose();
        }

Ответы [ 2 ]

0 голосов
/ 18 мая 2010

Я почти уверен, что вы правы относительно преобразования символов ASCII. Я немного искал поддерживаемые скалярные функции для двигателя Jet, но не смог их найти ... точнее я нашел скалярные функции в списке, но без синтаксиса. Функция CONVERT, вероятно, то, что вы хотите. Что-то вроде:

SELECT CONVERT(twobytefield, SQL_BINARY) from astm2007

Тогда вы можете позвонить dr.GetBytes(), чтобы прочитать необработанные данные. Однако я не смог построить оператор, используя ту функцию, которая понравилась двигателю Jet.

Если вы не можете заставить преобразование работать, другой возможностью является использование Advantage .NET Data Provider . Или провайдер OLE DB (но провайдер данных .NET может быть лучше, так как вы используете C #). Этот провайдер читает файлы DBF и поддерживает скалярную функцию CONVERT. Имеется бесплатный местный движок.

Поскольку вы упомянули, что собираетесь попробовать это, и поскольку я проверил это, чтобы убедиться, что я не лгу, вот фрагмент кода, который я использовал:

AdsConnection conn = new AdsConnection( 
   @"data source=c:\path;chartype=ansi;ServerType=local;TableType=cdx;" );
conn.Open();
AdsCommand cmd = conn.CreateCommand();
cmd.CommandText = "select cast(somefield as sql_binary) from sometable";
cmd.CommandType = CommandType.Text;
AdsExtendedReader rdr = cmd.ExecuteExtendedReader();
rdr.Read();
byte[] c0 = rdr.GetBytes( 0 );
int i0 = BitConverter.ToInt16( c0, 0 );
Console.WriteLine( "val = {0}", i0 );
0 голосов
/ 18 мая 2010

То, с чем вы можете столкнуться - это поле на основе заметок ... Это столбцы, которые на самом деле содержат необработанный текст в ДРУГОМ файле (обычно это .DBT (dBASE) или .FPT (FoxPro). Это смещение указателя в текстовом файле с произвольной длиной, записанным в блоках, но указатель хранится в 4 байтах.

Если у вас есть доступ к программе просмотра .dbf, и вы можете видеть ее несколько естественным образом, это, вероятно, поможет вам.

...