DBF Большое поле чарса - PullRequest
       40

DBF Большое поле чарса

1 голос
/ 16 апреля 2009

У меня есть файл базы данных, который, как я полагаю, был создан с помощью Clipper, но не могу сказать наверняка (у меня есть файлы .ntx для индексов, которые, как я понимаю, использует Clipper). Я пытаюсь создать приложение C #, которое будет читать эту базу данных, используя пространство имен System.Data.OleDB.

По большей части я могу успешно прочитать содержимое таблиц, но есть одно поле, которое я не могу. Это поле называется CTRLNUMS, которое определено как CHAR (750). Я читал различные статьи, найденные в поиске Google, в которых предлагается, чтобы поле размером более 255 символов было прочитано в процессе, отличном от обычного присвоения строковой переменной. Пока что мне не удалось найти подход, который я нашел.

Ниже приведен пример фрагмента кода, который я использую для чтения таблицы, и включает две опции, которые я использовал для чтения поля CTRLNUMS. Обе опции привели к возвращению 238 символов, хотя в поле хранится 750 символов.

Вот моя строка подключения:

Поставщик = Microsoft.Jet.OLEDB.4.0; Источник данных = c: \ datadir; Расширенные свойства = DBASE IV;

Может кто-нибудь сказать мне секрет чтения больших полей из файла DBF?

using (OleDbConnection conn = new OleDbConnection(connectionString))
{
    conn.Open();

    using (OleDbCommand cmd = new OleDbCommand())
    {
        cmd.Connection = conn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = string.Format("SELECT ITEM,CTRLNUMS FROM STUFF WHERE ITEM = '{0}'", stuffId);

        using (OleDbDataReader dr = cmd.ExecuteReader())
        {
            if (dr.Read())
            {
                stuff.StuffId = dr["ITEM"].ToString();

                // OPTION 1
                string ctrlNums = dr["CTRLNUMS"].ToString();

                // OPTION 2
                char[] buffer = new char[750];
                int index = 0;
                int readSize = 5;
                while (index < 750)
                {
                    long charsRead = dr.GetChars(dr.GetOrdinal("CTRLNUMS"), index, buffer, index, readSize);

                    index += (int)charsRead;

                    if (charsRead < readSize)
                    {
                        break;
                    }
                }
            }
        }
    }
}

Ответы [ 3 ]

3 голосов
/ 16 апреля 2009

Описание структуры DBF можно найти здесь: http://www.dbf2002.com/dbf-file-format.html

Я думаю, что использовал Clipper, чтобы изменить структуру поля таким образом, чтобы в полях символов десятичные разряды содержали старший байт размера, поэтому размеры полей символов действительно были равны 256 * десятичных дробей + размер.

У меня может быть класс C #, который читает dbfs (изначально, а не ADO / DAO), он может быть изменен для обработки этого случая. Дайте мне знать, если вы заинтересованы.

1 голос
/ 08 июня 2009

Вы все еще ищете ответ? Это разовая работа или что-то, что нужно делать регулярно?

У меня есть модуль Python, который в первую очередь предназначен для извлечения данных из всех видов файлов DBF ... он еще не обрабатывает хак length_high_byte = decimal_places, но это тривиальное изменение. Я был бы очень рад (а) поделиться этим с вами и / или (б) получить копию такого файла DBF для тестирования.

Добавлено позже: добавлена ​​расширенная функция, которая проверена на файлах, которые я создал сам. Предложите поделиться кодом со всеми, кто хотел бы его протестировать. Все еще заинтересован в том, чтобы самостоятельно получить несколько «настоящих» файлов для тестирования.

0 голосов
/ 16 апреля 2009

3 предложения, которые могут быть полезны ...

1 - используйте Access для создания связанной таблицы с файлом DBF, затем используйте .Net, чтобы попасть в таблицу в базе данных доступа, вместо того, чтобы идти прямо к DBF.

2 - попробуйте FoxPro OLEDB провайдер

3 - разобрать файл DBF вручную. Пример: здесь .

Я предполагаю, что # 1 должен работать проще всего, а # 3 даст вам возможность отточить свои навыки проклятия. :)

...