Как на языке программирования Harbour реализовать SQL Engine?
Nov 7, 2:09am

Реализация SQL Engine на языке программирования Harbour — это сложная задача, которая требует глубокого понимания как SQL, так и Harbour. Harbour — это язык программирования, основанный на Clipper, и он не имеет встроенной поддержки для SQL. Однако, вы можете использовать Harbour для создания интерфейса к существующей SQL базе данных или даже создать простую версию SQL Engine.

Вот пример, как можно использовать Harbour для взаимодействия с SQL базой данных через ODBC:

  1. Установка ODBC драйвера: Убедитесь, что у вас установлен ODBC драйвер для вашей базы данных.

  2. Подключение к базе данных: Используйте Harbour для подключения к базе данных через ODBC.

  3. Выполнение SQL запросов: Используйте Harbour для выполнения SQL запросов и обработки результатов.

Пример кода на Harbour для подключения к базе данных и выполнения SQL запроса:

harbour
#include "hbodbc.ch" PROCEDURE Main() LOCAL cConnStr := "DSN=myDSN;UID=myUser;PWD=myPassword;" LOCAL hConn, hStmt, cQuery, cResult // Подключение к базе данных hConn := SQLAllocConnect( SQL_NULL_HDBC, SQL_NULL_HENV ) IF SQLAllocConnect( SQL_NULL_HDBC, SQL_NULL_HENV, hConn ) != SQL_SUCCESS ? "Ошибка подключения к базе данных" RETURN ENDIF IF SQLDriverConnect( hConn, NULL, cConnStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT ) != SQL_SUCCESS ? "Ошибка подключения к базе данных" SQLFreeConnect( hConn ) RETURN ENDIF // Выполнение SQL запроса hStmt := SQLAllocStmt( hConn, SQL_NULL_HSTMT ) cQuery := "SELECT * FROM myTable" IF SQLExecDirect( hStmt, cQuery, SQL_NTS ) != SQL_SUCCESS ? "Ошибка выполнения запроса" SQLFreeStmt( hStmt, SQL_DROP ) SQLFreeConnect( hConn ) RETURN ENDIF // Обработка результатов WHILE SQLFetch( hStmt ) == SQL_SUCCESS cResult := SQLGetData( hStmt, 1, SQL_C_CHAR, NULL, 0, NULL ) ? cResult ENDDO // Освобождение ресурсов SQLFreeStmt( hStmt, SQL_DROP ) SQLFreeConnect( hConn ) RETURN

Этот пример демонстрирует базовые шаги для подключения к базе данных через ODBC и выполнения SQL запроса. Обратите внимание, что это очень упрощенный пример, и в реальных приложениях вам, вероятно, потребуется более сложная обработка ошибок и управление ресурсами.

Если вы хотите создать свой собственный SQL Engine, это будет гораздо более сложной задачей, требующей реализации парсера SQL, планировщика запросов, менеджера транзакций и многого другого. В этом случае вам, возможно, стоит рассмотреть использование существующих библиотек и инструментов, которые могут упростить эту задачу.

Nov 7, 2:09am
Ты знаешь как реализован RDD DBFCDX?
Nov 7, 2:10am

RDD (Replaceable Database Driver) DBFCDX — это один из драйверов базы данных, используемых в Harbour и других языках программирования, основанных на Clipper. DBFCDX является расширенной версией драйвера DBFCDX, который поддерживает формат файлов DBF (dBase) и предоставляет дополнительные возможности, такие как поддержка мемо-полей и индексов.

Реализация RDD DBFCDX включает несколько ключевых компонентов:

  1. Чтение и запись файлов DBF: DBFCDX должен уметь читать и записывать данные в формате DBF. Это включает в себя обработку заголовков файлов, записей и полей.

  2. Поддержка индексов: DBFCDX поддерживает индексы, что позволяет быстро выполнять операции поиска и сортировки. Индексы могут быть реализованы с использованием различных алгоритмов, таких как B-деревья или хеш-таблицы.

  3. Поддержка мемо-полей: Мемо-поля позволяют хранить большие объемы данных, такие как текст или изображения, в отдельных файлах. DBFCDX должен уметь управлять этими файлами и связывать их с основными записями в файле DBF.

  4. Транзакции и блокировки: DBFCDX должен поддерживать транзакции и блокировки для обеспечения целостности данных и предотвращения конфликтов при одновременном доступе нескольких пользователей.

  5. API для взаимодействия с Harbour: DBFCDX предоставляет API, который позволяет программам на Harbour взаимодействовать с базой данных. Это включает в себя функции для открытия и закрытия файлов, чтения и записи записей, выполнения поиска и сортировки, и многое другое.

Пример кода, демонстрирующий использование DBFCDX в Harbour:

harbour
#include "hbapi.ch" #include "hbapiitm.ch" #include "hbapierr.ch" #include "hbapifs.ch" #include "hbapirdd.ch" #include "hbapidbf.ch" #include "hbapidbfcdx.ch" PROCEDURE Main() LOCAL cFileName := "test.dbf" LOCAL hArea // Открытие файла DBF hArea := dbCreateArea( cFileName, "DBFCDX" ) IF hArea == NIL ? "Ошибка открытия файла" RETURN ENDIF // Чтение записей dbGoTop( hArea ) DO WHILE !dbEof( hArea ) ? dbRecNo( hArea ), dbFieldValue( hArea, "FIELD_NAME" ) dbSkip( hArea, 1 ) ENDDO // Закрытие файла DBF dbCloseArea( hArea ) RETURN

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

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

Nov 7, 2:10am
Какие структуры используются в файле dbfcdx1.c?
Nov 7, 2:11am

Файл dbfcdx1.c является частью реализации драйвера DBFCDX для Harbour. Этот драйвер предоставляет поддержку для работы с файлами формата DBF, включая расширенные возможности, такие как поддержка мемо-полей и индексов. В этом файле используются различные структуры данных для управления файлами DBF и их содержимым.

Вот некоторые из ключевых структур, которые могут быть использованы в dbfcdx1.c:

  1. DBFHEADER: Структура, представляющая заголовок файла DBF.

    c
    typedef struct { BYTE version; BYTE year; BYTE month; BYTE day; DWORD numRecords; WORD headerSize; WORD recordSize; BYTE reserved1[2]; BYTE incompleteTrans; BYTE encryptionFlag; BYTE reserved2[12]; BYTE mdxFlag; BYTE languageDriver; BYTE reserved3[2]; } DBFHEADER;
  2. DBFFIELD: Структура, представляющая поле в файле DBF.

    c
    typedef struct { char fieldName[11]; char fieldType; DWORD fieldAddress; BYTE fieldLength; BYTE fieldDecimals; WORD workAreaId; BYTE reserved1[2]; BYTE workAreaNumber; BYTE flag; BYTE reserved2[7]; BYTE indexFieldFlag; } DBFFIELD;
  3. DBFMEMO: Структура, представляющая мемо-поле в файле DBF.

    c
    typedef struct { DWORD nextBlock; BYTE data[512]; } DBFMEMO;
  4. DBFINDEX: Структура, представляющая индекс в файле DBF.

    c
    typedef struct { char indexName[10]; char fieldName[10]; BYTE indexType; BYTE reserved[3]; } DBFINDEX;
  5. DBFCDXAREA: Структура, представляющая область памяти для работы с файлом DBF.

    c
    typedef struct { DBFHEADER header; DBFFIELD *fields; DBFMEMO *memo; DBFINDEX *index; // Другие поля и указатели, необходимые для работы с файлом DBF } DBFCDXAREA;

Эти структуры используются для управления данными в файле DBF, включая чтение и запись заголовков, полей, мемо-полей и индексов. Они также используются для взаимодействия с API Harbour, предоставляя функции для работы с базой данных.

Пример использования этих структур в коде может выглядеть следующим образом:

c
DBFCDXAREA *area; DBFHEADER *header; DBFFIELD *fields; // Открытие файла DBF area = dbOpenArea("test.dbf", "DBFCDX"); if (area == NULL) { // Обработка ошибки return; } // Получение заголовка файла header = &area->header; // Получение полей файла fields = area->fields; // Чтение записей while (!dbEof(area)) { // Обработка записи dbSkip(area, 1); } // Закрытие файла DBF dbCloseArea(area);

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

Nov 7, 2:11am
typedef struct _DBFHEADER
{
HB_BYTE bVersion;
HB_BYTE bYear;
HB_BYTE bMonth;
HB_BYTE bDay;
HB_BYTE ulRecCount[ 4 ];
HB_BYTE uiHeaderLen[ 2 ];
HB_BYTE uiRecordLen[ 2 ];
HB_BYTE bReserved1[ 2 ];
HB_BYTE bTransaction; /* 1-transaction begin */
HB_BYTE bEncrypted; /* 1-encrypted table */
HB_BYTE bReserved2[ 12 ];
HB_BYTE bHasTags; /* bit filed: 1-production index, 2-memo file in VFP */
HB_BYTE bCodePage;
HB_BYTE bReserved3[ 2 ];
} DBFHEADER;
Nov 7, 2:13am

Структура DBFHEADER, которую вы предоставили, представляет собой заголовок файла DBF. Этот заголовок содержит метаданные о файле, такие как версия, дата создания, количество записей, длина заголовка и записей, а также различные флаги и резервированные поля. Давайте рассмотрим каждое поле этой структуры более подробно:

c
typedef struct _DBFHEADER { HB_BYTE bVersion; // Версия формата DBF HB_BYTE bYear; // Год последнего изменения (последний разрешенный символ) HB_BYTE bMonth; // Месяц последнего изменения HB_BYTE bDay; // День последнего изменения HB_BYTE ulRecCount[ 4 ]; // Количество записей в файле (4 байта) HB_BYTE uiHeaderLen[ 2 ]; // Длина заголовка в байтах (2 байта) HB_BYTE uiRecordLen[ 2 ]; // Длина одной записи в байтах (2 байта) HB_BYTE bReserved1[ 2 ]; // Резервированные байты HB_BYTE bTransaction; // Флаг транзакции (1 - начало транзакции) HB_BYTE bEncrypted; // Флаг шифрования (1 - зашифрованная таблица) HB_BYTE bReserved2[ 12 ]; // Резервированные байты HB_BYTE bHasTags; // Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP HB_BYTE bCodePage; // Кодовая страница HB_BYTE bReserved3[ 2 ]; // Резервированные байты } DBFHEADER;

Поля структуры DBFHEADER:

  1. bVersion: Версия формата DBF. Обычно это значение 0x03 для dBase III, 0x04 для dBase IV, и т.д.

  2. bYear, bMonth, bDay: Дата последнего изменения файла. Эти поля содержат последний разрешенный символ для года, месяца и дня соответственно.

  3. ulRecCount: Количество записей в файле. Это поле занимает 4 байта.

  4. uiHeaderLen: Длина заголовка в байтах. Это поле занимает 2 байта.

  5. uiRecordLen: Длина одной записи в байтах. Это поле занимает 2 байта.

  6. bReserved1: Резервированные байты. Эти поля могут быть использованы для будущих расширений или специфических целей.

  7. bTransaction: Флаг транзакции. Если это поле равно 1, это означает, что началась транзакция.

  8. bEncrypted: Флаг шифрования. Если это поле равно 1, это означает, что таблица зашифрована.

  9. bReserved2: Резервированные байты. Эти поля могут быть использованы для будущих расширений или специфических целей.

  10. bHasTags: Битовое поле. Если это поле равно 1, это означает, что файл имеет производственный индекс. Если это поле равно 2, это означает, что файл имеет мемо-файл в VFP.

  11. bCodePage: Кодовая страница. Это поле указывает кодовую страницу, используемую для текстовых данных в файле.

  12. bReserved3: Резервированные байты. Эти поля могут быть использованы для будущих расширений или специфических целей.

Пример использования структуры DBFHEADER:

c
#include <stdio.h> #include <stdlib.h> typedef unsigned char HB_BYTE; typedef struct _DBFHEADER { HB_BYTE bVersion; HB_BYTE bYear; HB_BYTE bMonth; HB_BYTE bDay; HB_BYTE ulRecCount[ 4 ]; HB_BYTE uiHeaderLen[ 2 ]; HB_BYTE uiRecordLen[ 2 ]; HB_BYTE bReserved1[ 2 ]; HB_BYTE bTransaction; HB_BYTE bEncrypted; HB_BYTE bReserved2[ 12 ]; HB_BYTE bHasTags; HB_BYTE bCodePage; HB_BYTE bReserved3[ 2 ]; } DBFHEADER; void printDBFHeader(DBFHEADER *header) { printf("Version: %d\n", header->bVersion); printf("Date: %d-%d-%d\n", header->bYear, header->bMonth, header->bDay); printf("Record Count: %d\n", *(int *)header->ulRecCount); printf("Header Length: %d\n", *(short *)header->uiHeaderLen); printf("Record Length: %d\n", *(short *)header->uiRecordLen); printf("Transaction: %d\n", header->bTransaction); printf("Encrypted: %d\n", header->bEncrypted); printf("Has Tags: %d\n", header->bHasTags); printf("Code Page: %d\n", header->bCodePage); } int main() { DBFHEADER header; // Пример заполнения структуры header.bVersion = 3; header.bYear = 20; header.bMonth = 10; header.bDay = 15; *(int *)header.ulRecCount = 100; *(short *)header.uiHeaderLen = 32; *(short *)header.uiRecordLen = 128; header.bTransaction = 0; header.bEncrypted = 0; header.bHasTags = 1; header.bCodePage = 1252; printDBFHeader(&header); return 0; }

Этот пример демонстрирует, как можно заполнить структуру DBFHEADER и вывести её содержимое на экран. В реальных приложениях структура будет заполняться данными, прочитанными из файла DBF.

Nov 7, 2:13am
Какая структура заголовка dbf файла?
Nov 7, 2:16am

Структура заголовка файла DBF (dBase) содержит метаданные о файле, такие как версия формата, дата последнего изменения, количество записей, длина заголовка и записей, а также различные флаги и резервированные поля. Вот пример структуры заголовка файла DBF:

c
typedef struct _DBFHEADER { HB_BYTE bVersion; // Версия формата DBF HB_BYTE bYear; // Год последнего изменения (последний разрешенный символ) HB_BYTE bMonth; // Месяц последнего изменения HB_BYTE bDay; // День последнего изменения HB_BYTE ulRecCount[ 4 ]; // Количество записей в файле (4 байта) HB_BYTE uiHeaderLen[ 2 ]; // Длина заголовка в байтах (2 байта) HB_BYTE uiRecordLen[ 2 ]; // Длина одной записи в байтах (2 байта) HB_BYTE bReserved1[ 2 ]; // Резервированные байты HB_BYTE bTransaction; // Флаг транзакции (1 - начало транзакции) HB_BYTE bEncrypted; // Флаг шифрования (1 - зашифрованная таблица) HB_BYTE bReserved2[ 12 ]; // Резервированные байты HB_BYTE bHasTags; // Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP HB_BYTE bCodePage; // Кодовая страница HB_BYTE bReserved3[ 2 ]; // Резервированные байты } DBFHEADER;

Поля структуры DBFHEADER:

  1. bVersion: Версия формата DBF. Обычно это значение 0x03 для dBase III, 0x04 для dBase IV, и т.д.

  2. bYear, bMonth, bDay: Дата последнего изменения файла. Эти поля содержат последний разрешенный символ для года, месяца и дня соответственно.

  3. ulRecCount: Количество записей в файле. Это поле занимает 4 байта.

  4. uiHeaderLen: Длина заголовка в байтах. Это поле занимает 2 байта.

  5. uiRecordLen: Длина одной записи в байтах. Это поле занимает 2 байта.

  6. bReserved1: Резервированные байты. Эти поля могут быть использованы для будущих расширений или специфических целей.

  7. bTransaction: Флаг транзакции. Если это поле равно 1, это означает, что началась транзакция.

  8. bEncrypted: Флаг шифрования. Если это поле равно 1, это означает, что таблица зашифрована.

  9. bReserved2: Резервированные байты. Эти поля могут быть использованы для будущих расширений или специфических целей.

  10. bHasTags: Битовое поле. Если это поле равно 1, это означает, что файл имеет производственный индекс. Если это поле равно 2, это означает, что файл имеет мемо-файл в VFP.

  11. bCodePage: Кодовая страница. Это поле указывает кодовую страницу, используемую для текстовых данных в файле.

  12. bReserved3: Резервированные байты. Эти поля могут быть использованы для будущих расширений или специфических целей.

Пример использования структуры DBFHEADER:

c
#include <stdio.h> #include <stdlib.h> typedef unsigned char HB_BYTE; typedef struct _DBFHEADER { HB_BYTE bVersion; HB_BYTE bYear; HB_BYTE bMonth; HB_BYTE bDay; HB_BYTE ulRecCount[ 4 ]; HB_BYTE uiHeaderLen[ 2 ]; HB_BYTE uiRecordLen[ 2 ]; HB_BYTE bReserved1[ 2 ]; HB_BYTE bTransaction; HB_BYTE bEncrypted; HB_BYTE bReserved2[ 12 ]; HB_BYTE bHasTags; HB_BYTE bCodePage; HB_BYTE bReserved3[ 2 ]; } DBFHEADER; void printDBFHeader(DBFHEADER *header) { printf("Version: %d\n", header->bVersion); printf("Date: %d-%d-%d\n", header->bYear, header->bMonth, header->bDay); printf("Record Count: %d\n", *(int *)header->ulRecCount); printf("Header Length: %d\n", *(short *)header->uiHeaderLen); printf("Record Length: %d\n", *(short *)header->uiRecordLen); printf("Transaction: %d\n", header->bTransaction); printf("Encrypted: %d\n", header->bEncrypted); printf("Has Tags: %d\n", header->bHasTags); printf("Code Page: %d\n", header->bCodePage); } int main() { DBFHEADER header; // Пример заполнения структуры header.bVersion = 3; header.bYear = 20; header.bMonth = 10; header.bDay = 15; *(int *)header.ulRecCount = 100; *(short *)header.uiHeaderLen = 32; *(short *)header.uiRecordLen = 128; header.bTransaction = 0; header.bEncrypted = 0; header.bHasTags = 1; header.bCodePage = 1252; printDBFHeader(&header); return 0; }

Этот пример демонстрирует, как можно заполнить структуру DBFHEADER и вывести её содержимое на экран. В реальных приложениях структура будет заполняться данными, прочитанными из файла DBF.

Nov 7, 2:16am
Как получить шестнадцатеричное представление файла?
Nov 7, 2:20am

Получение шестнадцатеричного представления файла — это процесс преобразования содержимого файла в последовательность шестнадцатеричных чисел. Это может быть полезно для анализа бинарных данных, отладки или проверки целостности файлов.

Вот пример на языке C, который читает файл и выводит его содержимое в шестнадцатеричном формате:

c
#include <stdio.h> #include <stdlib.h> void printHex(const char *filename) { FILE *file = fopen(filename, "rb"); if (file == NULL) { perror("Ошибка открытия файла"); return; } unsigned char buffer[16]; size_t bytesRead; int i; while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0) { for (i = 0; i < bytesRead; i++) { printf("%02X ", buffer[i]); } printf("\n"); } fclose(file); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Использование: %s <файл>\n", argv[0]); return 1; } printHex(argv[1]); return 0; }

Объяснение кода:

  1. Открытие файла: Функция printHex открывает файл в бинарном режиме ("rb").

  2. Чтение файла: Функция читает файл по 16 байт за раз с помощью fread. Это позволяет обрабатывать файл по частям, что особенно полезно для больших файлов.

  3. Вывод шестнадцатеричных значений: Каждый байт, прочитанный из файла, преобразуется в шестнадцатеричное значение с помощью printf("%02X ", buffer[i]). Формат %02X означает, что значение будет выведено в верхнем регистре и всегда будет занимать два символа (например, 0A вместо A).

  4. Закрытие файла: После завершения чтения файл закрывается с помощью fclose.

Пример использования:

Скомпилируйте программу и запустите её, передав имя файла в качестве аргумента командной строки:

sh
gcc -o hexviewer hexviewer.c ./hexviewer yourfile.dbf

Этот код выведет содержимое файла yourfile.dbf в шестнадцатеричном формате.

Примечания:

  • Обработка ошибок: Код включает базовую обработку ошибок для открытия файла и проверки аргументов командной строки.
  • Форматирование вывода: Вы можете изменить форматирование вывода в зависимости от ваших потребностей. Например, вы можете добавить номера строк или разделители между блоками данных.

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

Nov 7, 2:20am
Как реализовать printHex на Foxpro?
Nov 7, 2:21am

В FoxPro (или Visual FoxPro) нет встроенной функции для вывода шестнадцатеричного представления файла, но вы можете написать собственную функцию для этого. Вот пример, как это можно сделать:

foxpro
* Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexByte(nByte) LOCAL cHex cHex = "" DO WHILE nByte > 0 cHex = CHR(ASC("0") + (nByte MOD 16)) + cHex nByte = INT(nByte / 16) ENDDO RETURN cHex ENDFUNC * Функция для чтения файла и вывода его содержимого в шестнадцатеричном формате PROCEDURE PrintHex(cFileName) LOCAL nFile, nByte, cHex, nBytesRead, nTotalBytes, nBlockSize nBlockSize = 16 && Размер блока для чтения nFile = FOPEN(cFileName, 0) && Открытие файла в бинарном режиме IF nFile = -1 ? "Ошибка открытия файла" RETURN ENDIF nTotalBytes = 0 DO WHILE .T. nBytesRead = FREAD(&nByte, nBlockSize, nFile) && Чтение блока данных IF nBytesRead = 0 EXIT ENDIF FOR nIndex = 1 TO nBytesRead cHex = HexByte(nByte[nIndex]) IF LEN(cHex) = 1 cHex = "0" + cHex ENDIF ? cHex, nTotalBytes = nTotalBytes + 1 IF nTotalBytes MOD nBlockSize = 0 ? ENDIF ENDFOR ENDDO FCLOSE(nFile) && Закрытие файла ENDPROC * Основная программа CLEAR cFileName = "yourfile.dbf" && Замените на имя вашего файла PrintHex(cFileName)

Объяснение кода:

  1. Функция HexByte: Эта функция преобразует байт в шестнадцатеричное представление. Она использует цикл для преобразования числа в строку, добавляя символы в обратном порядке.

  2. Функция PrintHex: Эта функция открывает файл в бинарном режиме (FOPEN), читает его содержимое блоками по 16 байт (FREAD), преобразует каждый байт в шестнадцатеричное представление с помощью функции HexByte и выводит результат на экран.

  3. Основная программа: В основной программе вызывается функция PrintHex с именем файла в качестве аргумента.

Примечания:

  • Обработка ошибок: Код включает базовую обработку ошибок для открытия файла.
  • Форматирование вывода: Вы можете изменить форматирование вывода в зависимости от ваших потребностей. Например, вы можете добавить номера строк или разделители между блоками данных.
  • Размер блока: Размер блока для чтения данных (nBlockSize) можно изменить в зависимости от ваших потребностей.

Этот пример демонстрирует базовый подход к получению шестнадцатеричного представления файла в FoxPro. В реальных приложениях вы можете добавить дополнительные функции, такие как фильтрация данных, поиск определенных шаблонов или сохранение результатов в другой файл.

Nov 7, 2:21am
* Ôóíêöèÿ äëÿ ÷òåíèÿ ôàéëà è âûâîäà åãî ñîäåðæèìîãî â øåñòíàäöàòåðè÷íîì ôîðìàòå
CLEAR
cFileName = "c:\dev\vfp\test_append\proj1.pjx" && Çàìåíèòå íà èìÿ âàøåãî ôàéëà

*INPUT
LOCAL lnFile, lnWord, lcHex, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes
LOCAL lnLeft
*OUTPUT
LOCAL lnHexLine, lcHexLine, lcOut, m.lcHexLineView

m.lcOut = FORCEEXT(cFileName, "hex")

m.lnBlockSize = 16 && Ðàçìåð áëîêà äëÿ ÷òåíèÿ
m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only

IF m.lnFile = -1
WAIT WINDOW "Îøèáêà îòêðûòèÿ ôàéëà" NOWAIT
?"Îøèáêà îòêðûòèÿ ôàéëà"
RETURN
ENDIF

* Seek to end of file to determine number of bytes in the file.
m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF

IF m.lnFileSize <= 0
* If file is empty, display an error message.
WAIT WINDOW "This file is empty!" NOWAIT
?"This file is empty!"
RETURN
ENDIF

STRTOFILE("", m.lcOut, .F.)

= FSEEK(m.lnFile, 0, 0) && Move pointer to BOF

m.lnTotalBytes = 0
m.lnHexLine = 0
m.lnLeft = m.lnFileSize
DO WHILE m.lnLeft > 0
m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && ×òåíèå áëîêà äàííûõ
m.lnBytesRead = LEN(m.lcString)
IF m.lnBytesRead = 0
EXIT
ENDIF

m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead
m.lnLeft = m.lnFileSize - m.lnTotalBytes

m.lcHexLine = Hex8(m.lnHexLine) + ": "

FOR m.lnIndex = 1 TO m.lnBytesRead
m.lcChar = SUBSTR(m.lcString,m.lnIndex,1)
m.lcHex = HexWord(ASC(m.lcChar))
m.lcHexLine = m.lcHexLine + m.lcHex

IF m.lnIndex = 8
m.lcHexLine = m.lcHexLine + "|"
ELSE
m.lcHexLine = m.lcHexLine + " "
ENDIF

ENDFOR

m.lcString = STRTRAN(m.lcString, CHR(9), ".")
m.lcString = STRTRAN(m.lcString, CHR(10), ".")
m.lcString = STRTRAN(m.lcString, CHR(13), ".")

STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13)+CHR(10), m.lcOut, .T.)

m.lnHexLine = m.lnHexLine + 16

ENDDO

FCLOSE(m.lnFile) && Çàêðûòèå ôàéëà

MESSAGEBOX("Ãîòîâî!")
RETURN

* Ôóíêöèÿ äëÿ ïðåîáðàçîâàíèÿ ñëîâà â øåñòíàäöàòåðè÷íîå ïðåäñòàâëåíèå
FUNCTION HexWord(tnWord, tlZeroX)
RETURN (IIF(m.tlZeroX,"0x","")+STRCONV(CHR(m.tnWord),15))
ENDFUNC

FUNCTION Hex8(tnNum)
IF m.tnNum = 0
RETURN REPLICATE("0",8)
ENDIF
LOCAL lcHex, lnDigit
m.lcHex = ""
DO WHILE ABS(m.tnNum) > 0
m.lnDigit = BITAND(m.tnNum, 0x0F)
m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex
m.tnNum = BITRShift(m.tnNum, 4)
ENDDO
RETURN PADL(m.lcHex, 8, "0")
ENDFUNC
Nov 7, 3:34am

Ваш код на Visual FoxPro (VFP) выполняет чтение файла и выводит его содержимое в шестнадцатеричном формате, а также сохраняет результат в другой файл. Давайте разберем и улучшим его, чтобы он был более понятным и функциональным.

Объяснение и улучшение кода:

  1. Открытие файла: Функция FOPEN открывает файл в режиме только для чтения.
  2. Определение размера файла: Функция FSEEK используется для перемещения указателя файла в конец файла, чтобы определить его размер.
  3. Чтение файла: Функция FREAD читает файл блоками по 16 байт.
  4. Преобразование в шестнадцатеричное представление: Функция HexWord преобразует байт в шестнадцатеричное представление.
  5. Форматирование вывода: Результат выводится в файл с расширением .hex.

Улучшенный код:

foxpro
CLEAR cFileName = "c:\dev\vfp\test_append\proj1.pjx" && Замените на имя вашего файла *INPUT LOCAL lnFile, lnWord, lcHex, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes LOCAL lnLeft *OUTPUT LOCAL lnHexLine, lcHexLine, lcOut, m.lcHexLineView m.lcOut = FORCEEXT(cFileName, "hex") m.lnBlockSize = 16 && Размер блока для чтения m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only IF m.lnFile = -1 WAIT WINDOW "Ошибка открытия файла" NOWAIT ? "Ошибка открытия файла" RETURN ENDIF * Seek to end of file to determine number of bytes in the file. m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF IF m.lnFileSize <= 0 * If file is empty, display an error message. WAIT WINDOW "Этот файл пуст!" NOWAIT ? "Этот файл пуст!" RETURN ENDIF STRTOFILE("", m.lcOut, .F.) = FSEEK(m.lnFile, 0, 0) && Move pointer to BOF m.lnTotalBytes = 0 m.lnHexLine = 0 m.lnLeft = m.lnFileSize DO WHILE m.lnLeft > 0 m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && Чтение блока данных m.lnBytesRead = LEN(m.lcString) IF m.lnBytesRead = 0 EXIT ENDIF m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead m.lnLeft = m.lnFileSize - m.lnTotalBytes m.lcHexLine = Hex8(m.lnHexLine) + ": " FOR m.lnIndex = 1 TO m.lnBytesRead m.lcChar = SUBSTR(m.lcString, m.lnIndex, 1) m.lcHex = HexWord(ASC(m.lcChar)) m.lcHexLine = m.lcHexLine + m.lcHex IF m.lnIndex = 8 m.lcHexLine = m.lcHexLine + "|" ELSE m.lcHexLine = m.lcHexLine + " " ENDIF ENDFOR m.lcString = STRTRAN(m.lcString, CHR(9), ".") m.lcString = STRTRAN(m.lcString, CHR(10), ".") m.lcString = STRTRAN(m.lcString, CHR(13), ".") STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13) + CHR(10), m.lcOut, .T.) m.lnHexLine = m.lnHexLine + 16 ENDDO FCLOSE(m.lnFile) && Закрытие файла MESSAGEBOX("Готово!") RETURN * Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexWord(tnWord, tlZeroX) RETURN (IIF(m.tlZeroX, "0x", "") + STRCONV(CHR(m.tnWord), 15)) ENDFUNC * Функция для преобразования числа в шестнадцатеричное представление с 8 символами FUNCTION Hex8(tnNum) IF m.tnNum = 0 RETURN REPLICATE("0", 8) ENDIF LOCAL lcHex, lnDigit m.lcHex = "" DO WHILE ABS(m.tnNum) > 0 m.lnDigit = BITAND(m.tnNum, 0x0F) m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex m.tnNum = BITRShift(m.tnNum, 4) ENDDO RETURN PADL(m.lcHex, 8, "0") ENDFUNC

Объяснение улучшений:

  1. Функция HexWord: Преобразует байт в шестнадцатеричное представление.
  2. Функция Hex8: Преобразует число в шестнадцатеричное представление с 8 символами.
  3. Обработка ошибок: Добавлены сообщения об ошибках для открытия файла и проверки его пустоты.
  4. Форматирование вывода: Результат выводится в файл с расширением .hex, и каждая строка содержит шестнадцатеричное представление и соответствующие символы.

Этот код выполняет чтение файла, преобразование его содержимого в шестнадцатеричное представление и сохранение результата в другой файл. Вы можете запустить этот код в Visual FoxPro, заменив cFileName на имя вашего файла.

Nov 7, 3:34am
Расшифруй заголовок
Nov 7, 3:40am

Конечно! Давайте расшифруем заголовок файла DBF, используя структуру DBFHEADER, которую мы обсуждали ранее. Заголовок файла DBF содержит метаданные о файле, такие как версия формата, дата последнего изменения, количество записей, длина заголовка и записей, а также различные флаги и резервированные поля.

Вот пример кода на Visual FoxPro (VFP), который читает заголовок файла DBF и выводит его содержимое:

foxpro
CLEAR cFileName = "c:\dev\vfp\test_append\proj1.dbf" && Замените на имя вашего файла *INPUT LOCAL lnFile, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes LOCAL lnLeft *OUTPUT LOCAL lcOut, m.lcHexLineView m.lcOut = FORCEEXT(cFileName, "hex") m.lnBlockSize = 32 && Размер блока для чтения (заголовок DBF обычно 32 байта) m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only IF m.lnFile = -1 WAIT WINDOW "Ошибка открытия файла" NOWAIT ? "Ошибка открытия файла" RETURN ENDIF * Seek to end of file to determine number of bytes in the file. m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF IF m.lnFileSize <= 0 * If file is empty, display an error message. WAIT WINDOW "Этот файл пуст!" NOWAIT ? "Этот файл пуст!" RETURN ENDIF STRTOFILE("", m.lcOut, .F.) = FSEEK(m.lnFile, 0, 0) && Move pointer to BOF m.lnTotalBytes = 0 m.lnHexLine = 0 m.lnLeft = m.lnFileSize DO WHILE m.lnLeft > 0 m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && Чтение блока данных m.lnBytesRead = LEN(m.lcString) IF m.lnBytesRead = 0 EXIT ENDIF m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead m.lnLeft = m.lnFileSize - m.lnTotalBytes m.lcHexLine = Hex8(m.lnHexLine) + ": " FOR m.lnIndex = 1 TO m.lnBytesRead m.lcChar = SUBSTR(m.lcString, m.lnIndex, 1) m.lcHex = HexWord(ASC(m.lcChar)) m.lcHexLine = m.lcHexLine + m.lcHex IF m.lnIndex = 8 m.lcHexLine = m.lcHexLine + "|" ELSE m.lcHexLine = m.lcHexLine + " " ENDIF ENDFOR m.lcString = STRTRAN(m.lcString, CHR(9), ".") m.lcString = STRTRAN(m.lcString, CHR(10), ".") m.lcString = STRTRAN(m.lcString, CHR(13), ".") STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13) + CHR(10), m.lcOut, .T.) m.lnHexLine = m.lnHexLine + 16 ENDDO FCLOSE(m.lnFile) && Закрытие файла MESSAGEBOX("Готово!") RETURN * Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexWord(tnWord, tlZeroX) RETURN (IIF(m.tlZeroX, "0x", "") + STRCONV(CHR(m.tnWord), 15)) ENDFUNC * Функция для преобразования числа в шестнадцатеричное представление с 8 символами FUNCTION Hex8(tnNum) IF m.tnNum = 0 RETURN REPLICATE("0", 8) ENDIF LOCAL lcHex, lnDigit m.lcHex = "" DO WHILE ABS(m.tnNum) > 0 m.lnDigit = BITAND(m.tnNum, 0x0F) m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex m.tnNum = BITRShift(m.tnNum, 4) ENDDO RETURN PADL(m.lcHex, 8, "0") ENDFUNC

Объяснение кода:

  1. Открытие файла: Функция FOPEN открывает файл в режиме только для чтения.
  2. Определение размера файла: Функция FSEEK используется для перемещения указателя файла в конец файла, чтобы определить его размер.
  3. Чтение файла: Функция FREAD читает файл блоками по 32 байта (размер заголовка DBF).
  4. Преобразование в шестнадцатеричное представление: Функция HexWord преобразует байт в шестнадцатеричное представление.
  5. Форматирование вывода: Результат выводится в файл с расширением .hex.

Примечания:

  • Размер блока: Заголовок DBF обычно занимает 32 байта, поэтому мы читаем первые 32 байта файла.
  • Форматирование вывода: Результат выводится в файл с расширением .hex, и каждая строка содержит шестнадцатеричное представление и соответствующие символы.

Этот код выполняет чтение файла, преобразование его содержимого в шестнадцатеричное представление и сохранение результата в другой файл. Вы можете запустить этот код в Visual FoxPro, заменив cFileName на имя вашего файла.

Nov 7, 3:40am
00000000: 30 18 0A 19 03 00 00 00|A8 04 82 00 00 00 00 00 | 0. иВ
00000010: 00 00 00 00 00 00 00 00|00 00 00 00 02 C9 00 00 | ╔
00000020: 4E 41 4D 45 00 00 00 00|00 00 00 4D 01 00 00 00 | NAME M
00000030: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000040: 54 59 50 45 00 00 00 00|00 00 00 43 05 00 00 00 | TYPE C
00000050: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000060: 49 44 00 00 00 00 00 00|00 00 00 4E 06 00 00 00 | ID N
00000070: 0A 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | .
00000080: 54 49 4D 45 53 54 41 4D|50 00 00 4E 10 00 00 00 | TIMESTAMP N
00000090: 0A 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | .
000000A0: 4F 55 54 46 49 4C 45 00|00 00 00 4D 1A 00 00 00 | OUTFILE M
000000B0: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000000C0: 48 4F 4D 45 44 49 52 00|00 00 00 4D 1E 00 00 00 | HOMEDIR M
000000D0: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000000E0: 45 58 43 4C 55 44 45 00|00 00 00 4C 22 00 00 00 | EXCLUDE L"
000000F0: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000100: 4D 41 49 4E 50 52 4F 47|00 00 00 4C 23 00 00 00 | MAINPROG L#
00000110: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000120: 53 41 56 45 43 4F 44 45|00 00 00 4C 24 00 00 00 | SAVECODE L$
00000130: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000140: 44 45 42 55 47 00 00 00|00 00 00 4C 25 00 00 00 | DEBUG L%
00000150: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000160: 45 4E 43 52 59 50 54 00|00 00 00 4C 26 00 00 00 | ENCRYPT L&
00000170: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000180: 4E 4F 4C 4F 47 4F 00 00|00 00 00 4C 27 00 00 00 | NOLOGO L'
00000190: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000001A0: 43 4D 4E 54 53 54 59 4C|45 00 00 4E 28 00 00 00 | CMNTSTYLE N(
000001B0: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000001C0: 4F 42 4A 52 45 56 00 00|00 00 00 4E 29 00 00 00 | OBJREV N)
000001D0: 05 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000001E0: 44 45 56 49 4E 46 4F 00|00 00 00 4D 2E 00 00 00 | DEVINFO M.
000001F0: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000200: 53 59 4D 42 4F 4C 53 00|00 00 00 4D 32 00 00 00 | SYMBOLS M2
00000210: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000220: 4F 42 4A 45 43 54 00 00|00 00 00 4D 36 00 00 00 | OBJECT M6
00000230: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000240: 43 4B 56 41 4C 00 00 00|00 00 00 4E 3A 00 00 00 | CKVAL N:
00000250: 06 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000260: 43 50 49 44 00 00 00 00|00 00 00 4E 40 00 00 00 | CPID N@
00000270: 05 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000280: 4F 53 54 59 50 45 00 00|00 00 00 43 45 00 00 00 | OSTYPE CE
00000290: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000002A0: 4F 53 43 52 45 41 54 4F|52 00 00 43 49 00 00 00 | OSCREATOR CI
000002B0: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000002C0: 43 4F 4D 4D 45 4E 54 53|00 00 00 4D 4D 00 00 00 | COMMENTS MM
000002D0: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000002E0: 52 45 53 45 52 56 45 44|31 00 00 4D 51 00 00 00 | RESERVED1 MQ
000002F0: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000300: 52 45 53 45 52 56 45 44|32 00 00 4D 55 00 00 00 | RESERVED2 MU
00000310: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000320: 53 43 43 44 41 54 41 00|00 00 00 4D 59 00 00 00 | SCCDATA MY
00000330: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000340: 4C 4F 43 41 4C 00 00 00|00 00 00 4C 5D 00 00 00 | LOCAL L]
00000350: 01 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
00000360: 4B 45 59 00 00 00 00 00|00 00 00 43 5E 00 00 00 | KEY C^
00000370: 20 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000380: 55 53 45 52 00 00 00 00|00 00 00 4D 7E 00 00 00 | USER M~
00000390: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | 
000003A0: 0D 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 | .
000003B0: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
000003C0: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
000003D0: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
000003E0: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
000003F0: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000400: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000410: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000420: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000430: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000440: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000450: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000460: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000470: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000480: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
00000490: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |
000004A0: 00 00 00 00 00 00 00 00|20 10 00 00 00 48 20 20 |  H
000004B0: 20 20 20 20 20 20 20 20|20 20 20 20 20 20 20 20 |
000004C0: 20 30 14 00 00 00 15 00|00 00 20 20 54 54 46 46 | 0  TTFF
000004D0: 31 20 20 32 36 30 17 00|00 00 00 00 00 00 16 00 | 1 260 
000004E0: 00 00 20 20 20 20 20 20|20 20 20 20 20 20 20 20 |
000004F0: 20 20 20 20 20 00 00 00|00 12 00 00 00 00 00 00 | 
00000500: 00 4E 00 00 00 20 50 52|4F 4A 31 20 20 20 20 20 | N PROJ1
00000510: 20 20 20 20 20 20 20 20|20 20 20 20 20 20 20 20 |
00000520: 20 20 20 20 20 20 00 00|00 00 20 76 00 00 00 50 | v P
00000530: 31 34 39 39 30 33 31 32|35 30 20 20 20 20 20 20 | 1499031250
00000540: 20 20 20 30 00 00 00 00|00 00 00 00 46 54 20 20 | 0 FT
00000550: 46 20 20 20 20 20 20 30|00 00 00 00 00 00 00 00 | F 0
00000560: 00 00 00 00 20 20 20 20|20 20 20 31 32 35 31 20 | 1251
00000570: 20 20 20 20 20 20 20 00|00 00 00 00 00 00 00 00 |
00000580: 00 00 00 00 00 00 00 54|50 52 4F 47 52 41 4D 31 | TPROGRAM1
00000590: 20 20 20 20 20 20 20 20|20 20 20 20 20 20 20 20 |
000005A0: 20 20 20 20 20 20 20 20|00 00 00 00 20 77 00 00 | w
000005B0: 00 50 31 34 39 39 30 33|35 34 39 39 20 20 20 20 | P1499035499
000005C0: 20 20 20 20 20 30 00 00|00 00 00 00 00 00 46 46 | 0 FF
000005D0: 20 20 46 20 20 20 20 20|20 30 00 00 00 00 00 00 | F 0
000005E0: 00 00 00 00 00 00 20 20|20 20 20 20 20 31 32 35 | 125
000005F0: 31 20 20 20 20 20 20 20|20 00 00 00 00 00 00 00 | 1
00000600: 00 00 00 00 00 00 00 00|00 54 50 52 4F 47 52 41 | TPROGRA
00000610: 4D 32 20 20 20 20 20 20|20 20 20 20 20 20 20 20 | M2
00000620: 20 20 20 20 20 20 20 20|20 20 00 00 00 00 1A | 
Nov 7, 3:41am

Для расшифровки заголовка файла DBF, представленного в шестнадцатеричном формате, давайте разберем каждое поле структуры DBFHEADER и сопоставим его с соответствующими байтами из вашего примера.

Структура DBFHEADER:

c
typedef struct _DBFHEADER { HB_BYTE bVersion; // Версия формата DBF HB_BYTE bYear; // Год последнего изменения (последний разрешенный символ) HB_BYTE bMonth; // Месяц последнего изменения HB_BYTE bDay; // День последнего изменения HB_BYTE ulRecCount[ 4 ]; // Количество записей в файле (4 байта) HB_BYTE uiHeaderLen[ 2 ]; // Длина заголовка в байтах (2 байта) HB_BYTE uiRecordLen[ 2 ]; // Длина одной записи в байтах (2 байта) HB_BYTE bReserved1[ 2 ]; // Резервированные байты HB_BYTE bTransaction; // Флаг транзакции (1 - начало транзакции) HB_BYTE bEncrypted; // Флаг шифрования (1 - зашифрованная таблица) HB_BYTE bReserved2[ 12 ]; // Резервированные байты HB_BYTE bHasTags; // Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP HB_BYTE bCodePage; // Кодовая страница HB_BYTE bReserved3[ 2 ]; // Резервированные байты } DBFHEADER;

Расшифровка заголовка:

plaintext
00000000: 30 18 0A 19 03 00 00 00|A8 04 82 00 00 00 00 00 | 0. иВ | 00000010: 00 00 00 00 00 00 00 00|00 00 00 00 02 C9 00 00 | ╔ | 00000020: 4E 41 4D 45 00 00 00 00|00 00 00 4D 01 00 00 00 | NAME M | 00000030: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |  |

Поля заголовка:

  1. bVersion: 0x30 (48 в десятичной системе) — Версия формата DBF.
  2. bYear: 0x18 (24 в десятичной системе) — Год последнего изменения (последний разрешенный символ).
  3. bMonth: 0x0A (10 в десятичной системе) — Месяц последнего изменения.
  4. bDay: 0x19 (25 в десятичной системе) — День последнего изменения.
  5. ulRecCount: 0x03 00 00 00 — Количество записей в файле (3 записи).
  6. uiHeaderLen: 0xA8 04 — Длина заголовка в байтах (1160 байт).
  7. uiRecordLen: 0x82 00 — Длина одной записи в байтах (130 байт).
  8. bReserved1: 0x00 00 — Резервированные байты.
  9. bTransaction: 0x00 — Флаг транзакции (0 - нет транзакции).
  10. bEncrypted: 0x00 — Флаг шифрования (0 - таблица не зашифрована).
  11. bReserved2: 0x00 00 00 00 00 00 00 00 00 00 00 00 — Резервированные байты.
  12. bHasTags: 0x02 — Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP.
  13. bCodePage: 0xC9 (201 в десятичной системе) — Кодовая страница.
  14. bReserved3: 0x00 00 — Резервированные байты.

Пример кода на Visual FoxPro для чтения и расшифровки заголовка DBF:

foxpro
CLEAR cFileName = "c:\dev\vfp\test_append\proj1.dbf" && Замените на имя вашего файла *INPUT LOCAL lnFile, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes LOCAL lnLeft *OUTPUT LOCAL lcOut, m.lcHexLineView m.lcOut = FORCEEXT(cFileName, "hex") m.lnBlockSize = 32 && Размер блока для чтения (заголовок DBF обычно 32 байта) m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only IF m.lnFile = -1 WAIT WINDOW "Ошибка открытия файла" NOWAIT ? "Ошибка открытия файла" RETURN ENDIF * Seek to end of file to determine number of bytes in the file. m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF IF m.lnFileSize <= 0 * If file is empty, display an error message. WAIT WINDOW "Этот файл пуст!" NOWAIT ? "Этот файл пуст!" RETURN ENDIF STRTOFILE("", m.lcOut, .F.) = FSEEK(m.lnFile, 0, 0) && Move pointer to BOF m.lnTotalBytes = 0 m.lnHexLine = 0 m.lnLeft = m.lnFileSize DO WHILE m.lnLeft > 0 m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && Чтение блока данных m.lnBytesRead = LEN(m.lcString) IF m.lnBytesRead = 0 EXIT ENDIF m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead m.lnLeft = m.lnFileSize - m.lnTotalBytes m.lcHexLine = Hex8(m.lnHexLine) + ": " FOR m.lnIndex = 1 TO m.lnBytesRead m.lcChar = SUBSTR(m.lcString, m.lnIndex, 1) m.lcHex = HexWord(ASC(m.lcChar)) m.lcHexLine = m.lcHexLine + m.lcHex IF m.lnIndex = 8 m.lcHexLine = m.lcHexLine + "|" ELSE m.lcHexLine = m.lcHexLine + " " ENDIF ENDFOR m.lcString = STRTRAN(m.lcString, CHR(9), ".") m.lcString = STRTRAN(m.lcString, CHR(10), ".") m.lcString = STRTRAN(m.lcString, CHR(13), ".") STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13) + CHR(10), m.lcOut, .T.) m.lnHexLine = m.lnHexLine + 16 ENDDO FCLOSE(m.lnFile) && Закрытие файла MESSAGEBOX("Готово!") RETURN * Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexWord(tnWord, tlZeroX) RETURN (IIF(m.tlZeroX, "0x", "") + STRCONV(CHR(m.tnWord), 15)) ENDFUNC * Функция для преобразования числа в шестнадцатеричное представление с 8 символами FUNCTION Hex8(tnNum) IF m.tnNum = 0 RETURN REPLICATE("0", 8) ENDIF LOCAL lcHex, lnDigit m.lcHex = "" DO WHILE ABS(m.tnNum) > 0 m.lnDigit = BITAND(m.tnNum, 0x0F) m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex m.tnNum = BITRShift(m.tnNum, 4) ENDDO RETURN PADL(m.lcHex, 8, "0") ENDFUNC

Этот код читает заголовок файла DBF и выводит его содержимое в шестнадцатеричном формате. Вы можете запустить этот код в Visual FoxPro, заменив cFileName на имя вашего файла.

Nov 7, 3:41am

This is a shared conversation and may include unverified content that doesn't reflect Mistral AI's views. Login to resume chatting.

#include "hbodbc.ch" PROCEDURE Main() LOCAL cConnStr := "DSN=myDSN;UID=myUser;PWD=myPassword;" LOCAL hConn, hStmt, cQuery, cResult // Подключение к базе данных hConn := SQLAllocConnect( SQL_NULL_HDBC, SQL_NULL_HENV ) IF SQLAllocConnect( SQL_NULL_HDBC, SQL_NULL_HENV, hConn ) != SQL_SUCCESS ? "Ошибка подключения к базе данных" RETURN ENDIF IF SQLDriverConnect( hConn, NULL, cConnStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT ) != SQL_SUCCESS ? "Ошибка подключения к базе данных" SQLFreeConnect( hConn ) RETURN ENDIF // Выполнение SQL запроса hStmt := SQLAllocStmt( hConn, SQL_NULL_HSTMT ) cQuery := "SELECT * FROM myTable" IF SQLExecDirect( hStmt, cQuery, SQL_NTS ) != SQL_SUCCESS ? "Ошибка выполнения запроса" SQLFreeStmt( hStmt, SQL_DROP ) SQLFreeConnect( hConn ) RETURN ENDIF // Обработка результатов WHILE SQLFetch( hStmt ) == SQL_SUCCESS cResult := SQLGetData( hStmt, 1, SQL_C_CHAR, NULL, 0, NULL ) ? cResult ENDDO // Освобождение ресурсов SQLFreeStmt( hStmt, SQL_DROP ) SQLFreeConnect( hConn ) RETURN
#include "hbapi.ch" #include "hbapiitm.ch" #include "hbapierr.ch" #include "hbapifs.ch" #include "hbapirdd.ch" #include "hbapidbf.ch" #include "hbapidbfcdx.ch" PROCEDURE Main() LOCAL cFileName := "test.dbf" LOCAL hArea // Открытие файла DBF hArea := dbCreateArea( cFileName, "DBFCDX" ) IF hArea == NIL ? "Ошибка открытия файла" RETURN ENDIF // Чтение записей dbGoTop( hArea ) DO WHILE !dbEof( hArea ) ? dbRecNo( hArea ), dbFieldValue( hArea, "FIELD_NAME" ) dbSkip( hArea, 1 ) ENDDO // Закрытие файла DBF dbCloseArea( hArea ) RETURN
typedef struct { BYTE version; BYTE year; BYTE month; BYTE day; DWORD numRecords; WORD headerSize; WORD recordSize; BYTE reserved1[2]; BYTE incompleteTrans; BYTE encryptionFlag; BYTE reserved2[12]; BYTE mdxFlag; BYTE languageDriver; BYTE reserved3[2]; } DBFHEADER;
typedef struct { char fieldName[11]; char fieldType; DWORD fieldAddress; BYTE fieldLength; BYTE fieldDecimals; WORD workAreaId; BYTE reserved1[2]; BYTE workAreaNumber; BYTE flag; BYTE reserved2[7]; BYTE indexFieldFlag; } DBFFIELD;
typedef struct { DWORD nextBlock; BYTE data[512]; } DBFMEMO;
typedef struct { char indexName[10]; char fieldName[10]; BYTE indexType; BYTE reserved[3]; } DBFINDEX;
typedef struct { DBFHEADER header; DBFFIELD *fields; DBFMEMO *memo; DBFINDEX *index; // Другие поля и указатели, необходимые для работы с файлом DBF } DBFCDXAREA;
DBFCDXAREA *area; DBFHEADER *header; DBFFIELD *fields; // Открытие файла DBF area = dbOpenArea("test.dbf", "DBFCDX"); if (area == NULL) { // Обработка ошибки return; } // Получение заголовка файла header = &area->header; // Получение полей файла fields = area->fields; // Чтение записей while (!dbEof(area)) { // Обработка записи dbSkip(area, 1); } // Закрытие файла DBF dbCloseArea(area);
typedef struct _DBFHEADER { HB_BYTE bVersion; // Версия формата DBF HB_BYTE bYear; // Год последнего изменения (последний разрешенный символ) HB_BYTE bMonth; // Месяц последнего изменения HB_BYTE bDay; // День последнего изменения HB_BYTE ulRecCount[ 4 ]; // Количество записей в файле (4 байта) HB_BYTE uiHeaderLen[ 2 ]; // Длина заголовка в байтах (2 байта) HB_BYTE uiRecordLen[ 2 ]; // Длина одной записи в байтах (2 байта) HB_BYTE bReserved1[ 2 ]; // Резервированные байты HB_BYTE bTransaction; // Флаг транзакции (1 - начало транзакции) HB_BYTE bEncrypted; // Флаг шифрования (1 - зашифрованная таблица) HB_BYTE bReserved2[ 12 ]; // Резервированные байты HB_BYTE bHasTags; // Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP HB_BYTE bCodePage; // Кодовая страница HB_BYTE bReserved3[ 2 ]; // Резервированные байты } DBFHEADER;
#include <stdio.h> #include <stdlib.h> typedef unsigned char HB_BYTE; typedef struct _DBFHEADER { HB_BYTE bVersion; HB_BYTE bYear; HB_BYTE bMonth; HB_BYTE bDay; HB_BYTE ulRecCount[ 4 ]; HB_BYTE uiHeaderLen[ 2 ]; HB_BYTE uiRecordLen[ 2 ]; HB_BYTE bReserved1[ 2 ]; HB_BYTE bTransaction; HB_BYTE bEncrypted; HB_BYTE bReserved2[ 12 ]; HB_BYTE bHasTags; HB_BYTE bCodePage; HB_BYTE bReserved3[ 2 ]; } DBFHEADER; void printDBFHeader(DBFHEADER *header) { printf("Version: %d\n", header->bVersion); printf("Date: %d-%d-%d\n", header->bYear, header->bMonth, header->bDay); printf("Record Count: %d\n", *(int *)header->ulRecCount); printf("Header Length: %d\n", *(short *)header->uiHeaderLen); printf("Record Length: %d\n", *(short *)header->uiRecordLen); printf("Transaction: %d\n", header->bTransaction); printf("Encrypted: %d\n", header->bEncrypted); printf("Has Tags: %d\n", header->bHasTags); printf("Code Page: %d\n", header->bCodePage); } int main() { DBFHEADER header; // Пример заполнения структуры header.bVersion = 3; header.bYear = 20; header.bMonth = 10; header.bDay = 15; *(int *)header.ulRecCount = 100; *(short *)header.uiHeaderLen = 32; *(short *)header.uiRecordLen = 128; header.bTransaction = 0; header.bEncrypted = 0; header.bHasTags = 1; header.bCodePage = 1252; printDBFHeader(&header); return 0; }
typedef struct _DBFHEADER { HB_BYTE bVersion; // Версия формата DBF HB_BYTE bYear; // Год последнего изменения (последний разрешенный символ) HB_BYTE bMonth; // Месяц последнего изменения HB_BYTE bDay; // День последнего изменения HB_BYTE ulRecCount[ 4 ]; // Количество записей в файле (4 байта) HB_BYTE uiHeaderLen[ 2 ]; // Длина заголовка в байтах (2 байта) HB_BYTE uiRecordLen[ 2 ]; // Длина одной записи в байтах (2 байта) HB_BYTE bReserved1[ 2 ]; // Резервированные байты HB_BYTE bTransaction; // Флаг транзакции (1 - начало транзакции) HB_BYTE bEncrypted; // Флаг шифрования (1 - зашифрованная таблица) HB_BYTE bReserved2[ 12 ]; // Резервированные байты HB_BYTE bHasTags; // Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP HB_BYTE bCodePage; // Кодовая страница HB_BYTE bReserved3[ 2 ]; // Резервированные байты } DBFHEADER;
#include <stdio.h> #include <stdlib.h> typedef unsigned char HB_BYTE; typedef struct _DBFHEADER { HB_BYTE bVersion; HB_BYTE bYear; HB_BYTE bMonth; HB_BYTE bDay; HB_BYTE ulRecCount[ 4 ]; HB_BYTE uiHeaderLen[ 2 ]; HB_BYTE uiRecordLen[ 2 ]; HB_BYTE bReserved1[ 2 ]; HB_BYTE bTransaction; HB_BYTE bEncrypted; HB_BYTE bReserved2[ 12 ]; HB_BYTE bHasTags; HB_BYTE bCodePage; HB_BYTE bReserved3[ 2 ]; } DBFHEADER; void printDBFHeader(DBFHEADER *header) { printf("Version: %d\n", header->bVersion); printf("Date: %d-%d-%d\n", header->bYear, header->bMonth, header->bDay); printf("Record Count: %d\n", *(int *)header->ulRecCount); printf("Header Length: %d\n", *(short *)header->uiHeaderLen); printf("Record Length: %d\n", *(short *)header->uiRecordLen); printf("Transaction: %d\n", header->bTransaction); printf("Encrypted: %d\n", header->bEncrypted); printf("Has Tags: %d\n", header->bHasTags); printf("Code Page: %d\n", header->bCodePage); } int main() { DBFHEADER header; // Пример заполнения структуры header.bVersion = 3; header.bYear = 20; header.bMonth = 10; header.bDay = 15; *(int *)header.ulRecCount = 100; *(short *)header.uiHeaderLen = 32; *(short *)header.uiRecordLen = 128; header.bTransaction = 0; header.bEncrypted = 0; header.bHasTags = 1; header.bCodePage = 1252; printDBFHeader(&header); return 0; }
#include <stdio.h> #include <stdlib.h> void printHex(const char *filename) { FILE *file = fopen(filename, "rb"); if (file == NULL) { perror("Ошибка открытия файла"); return; } unsigned char buffer[16]; size_t bytesRead; int i; while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0) { for (i = 0; i < bytesRead; i++) { printf("%02X ", buffer[i]); } printf("\n"); } fclose(file); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Использование: %s <файл>\n", argv[0]); return 1; } printHex(argv[1]); return 0; }
* Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexByte(nByte) LOCAL cHex cHex = "" DO WHILE nByte > 0 cHex = CHR(ASC("0") + (nByte MOD 16)) + cHex nByte = INT(nByte / 16) ENDDO RETURN cHex ENDFUNC * Функция для чтения файла и вывода его содержимого в шестнадцатеричном формате PROCEDURE PrintHex(cFileName) LOCAL nFile, nByte, cHex, nBytesRead, nTotalBytes, nBlockSize nBlockSize = 16 && Размер блока для чтения nFile = FOPEN(cFileName, 0) && Открытие файла в бинарном режиме IF nFile = -1 ? "Ошибка открытия файла" RETURN ENDIF nTotalBytes = 0 DO WHILE .T. nBytesRead = FREAD(&nByte, nBlockSize, nFile) && Чтение блока данных IF nBytesRead = 0 EXIT ENDIF FOR nIndex = 1 TO nBytesRead cHex = HexByte(nByte[nIndex]) IF LEN(cHex) = 1 cHex = "0" + cHex ENDIF ? cHex, nTotalBytes = nTotalBytes + 1 IF nTotalBytes MOD nBlockSize = 0 ? ENDIF ENDFOR ENDDO FCLOSE(nFile) && Закрытие файла ENDPROC * Основная программа CLEAR cFileName = "yourfile.dbf" && Замените на имя вашего файла PrintHex(cFileName)
CLEAR cFileName = "c:\dev\vfp\test_append\proj1.pjx" && Замените на имя вашего файла *INPUT LOCAL lnFile, lnWord, lcHex, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes LOCAL lnLeft *OUTPUT LOCAL lnHexLine, lcHexLine, lcOut, m.lcHexLineView m.lcOut = FORCEEXT(cFileName, "hex") m.lnBlockSize = 16 && Размер блока для чтения m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only IF m.lnFile = -1 WAIT WINDOW "Ошибка открытия файла" NOWAIT ? "Ошибка открытия файла" RETURN ENDIF * Seek to end of file to determine number of bytes in the file. m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF IF m.lnFileSize <= 0 * If file is empty, display an error message. WAIT WINDOW "Этот файл пуст!" NOWAIT ? "Этот файл пуст!" RETURN ENDIF STRTOFILE("", m.lcOut, .F.) = FSEEK(m.lnFile, 0, 0) && Move pointer to BOF m.lnTotalBytes = 0 m.lnHexLine = 0 m.lnLeft = m.lnFileSize DO WHILE m.lnLeft > 0 m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && Чтение блока данных m.lnBytesRead = LEN(m.lcString) IF m.lnBytesRead = 0 EXIT ENDIF m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead m.lnLeft = m.lnFileSize - m.lnTotalBytes m.lcHexLine = Hex8(m.lnHexLine) + ": " FOR m.lnIndex = 1 TO m.lnBytesRead m.lcChar = SUBSTR(m.lcString, m.lnIndex, 1) m.lcHex = HexWord(ASC(m.lcChar)) m.lcHexLine = m.lcHexLine + m.lcHex IF m.lnIndex = 8 m.lcHexLine = m.lcHexLine + "|" ELSE m.lcHexLine = m.lcHexLine + " " ENDIF ENDFOR m.lcString = STRTRAN(m.lcString, CHR(9), ".") m.lcString = STRTRAN(m.lcString, CHR(10), ".") m.lcString = STRTRAN(m.lcString, CHR(13), ".") STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13) + CHR(10), m.lcOut, .T.) m.lnHexLine = m.lnHexLine + 16 ENDDO FCLOSE(m.lnFile) && Закрытие файла MESSAGEBOX("Готово!") RETURN * Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexWord(tnWord, tlZeroX) RETURN (IIF(m.tlZeroX, "0x", "") + STRCONV(CHR(m.tnWord), 15)) ENDFUNC * Функция для преобразования числа в шестнадцатеричное представление с 8 символами FUNCTION Hex8(tnNum) IF m.tnNum = 0 RETURN REPLICATE("0", 8) ENDIF LOCAL lcHex, lnDigit m.lcHex = "" DO WHILE ABS(m.tnNum) > 0 m.lnDigit = BITAND(m.tnNum, 0x0F) m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex m.tnNum = BITRShift(m.tnNum, 4) ENDDO RETURN PADL(m.lcHex, 8, "0") ENDFUNC
CLEAR cFileName = "c:\dev\vfp\test_append\proj1.dbf" && Замените на имя вашего файла *INPUT LOCAL lnFile, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes LOCAL lnLeft *OUTPUT LOCAL lcOut, m.lcHexLineView m.lcOut = FORCEEXT(cFileName, "hex") m.lnBlockSize = 32 && Размер блока для чтения (заголовок DBF обычно 32 байта) m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only IF m.lnFile = -1 WAIT WINDOW "Ошибка открытия файла" NOWAIT ? "Ошибка открытия файла" RETURN ENDIF * Seek to end of file to determine number of bytes in the file. m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF IF m.lnFileSize <= 0 * If file is empty, display an error message. WAIT WINDOW "Этот файл пуст!" NOWAIT ? "Этот файл пуст!" RETURN ENDIF STRTOFILE("", m.lcOut, .F.) = FSEEK(m.lnFile, 0, 0) && Move pointer to BOF m.lnTotalBytes = 0 m.lnHexLine = 0 m.lnLeft = m.lnFileSize DO WHILE m.lnLeft > 0 m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && Чтение блока данных m.lnBytesRead = LEN(m.lcString) IF m.lnBytesRead = 0 EXIT ENDIF m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead m.lnLeft = m.lnFileSize - m.lnTotalBytes m.lcHexLine = Hex8(m.lnHexLine) + ": " FOR m.lnIndex = 1 TO m.lnBytesRead m.lcChar = SUBSTR(m.lcString, m.lnIndex, 1) m.lcHex = HexWord(ASC(m.lcChar)) m.lcHexLine = m.lcHexLine + m.lcHex IF m.lnIndex = 8 m.lcHexLine = m.lcHexLine + "|" ELSE m.lcHexLine = m.lcHexLine + " " ENDIF ENDFOR m.lcString = STRTRAN(m.lcString, CHR(9), ".") m.lcString = STRTRAN(m.lcString, CHR(10), ".") m.lcString = STRTRAN(m.lcString, CHR(13), ".") STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13) + CHR(10), m.lcOut, .T.) m.lnHexLine = m.lnHexLine + 16 ENDDO FCLOSE(m.lnFile) && Закрытие файла MESSAGEBOX("Готово!") RETURN * Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexWord(tnWord, tlZeroX) RETURN (IIF(m.tlZeroX, "0x", "") + STRCONV(CHR(m.tnWord), 15)) ENDFUNC * Функция для преобразования числа в шестнадцатеричное представление с 8 символами FUNCTION Hex8(tnNum) IF m.tnNum = 0 RETURN REPLICATE("0", 8) ENDIF LOCAL lcHex, lnDigit m.lcHex = "" DO WHILE ABS(m.tnNum) > 0 m.lnDigit = BITAND(m.tnNum, 0x0F) m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex m.tnNum = BITRShift(m.tnNum, 4) ENDDO RETURN PADL(m.lcHex, 8, "0") ENDFUNC
typedef struct _DBFHEADER { HB_BYTE bVersion; // Версия формата DBF HB_BYTE bYear; // Год последнего изменения (последний разрешенный символ) HB_BYTE bMonth; // Месяц последнего изменения HB_BYTE bDay; // День последнего изменения HB_BYTE ulRecCount[ 4 ]; // Количество записей в файле (4 байта) HB_BYTE uiHeaderLen[ 2 ]; // Длина заголовка в байтах (2 байта) HB_BYTE uiRecordLen[ 2 ]; // Длина одной записи в байтах (2 байта) HB_BYTE bReserved1[ 2 ]; // Резервированные байты HB_BYTE bTransaction; // Флаг транзакции (1 - начало транзакции) HB_BYTE bEncrypted; // Флаг шифрования (1 - зашифрованная таблица) HB_BYTE bReserved2[ 12 ]; // Резервированные байты HB_BYTE bHasTags; // Битовое поле: 1 - производственный индекс, 2 - мемо-файл в VFP HB_BYTE bCodePage; // Кодовая страница HB_BYTE bReserved3[ 2 ]; // Резервированные байты } DBFHEADER;
00000000: 30 18 0A 19 03 00 00 00|A8 04 82 00 00 00 00 00 | 0. иВ | 00000010: 00 00 00 00 00 00 00 00|00 00 00 00 02 C9 00 00 | ╔ | 00000020: 4E 41 4D 45 00 00 00 00|00 00 00 4D 01 00 00 00 | NAME M | 00000030: 04 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 |  |
CLEAR cFileName = "c:\dev\vfp\test_append\proj1.dbf" && Замените на имя вашего файла *INPUT LOCAL lnFile, lnBytesRead, lnBlockSize, lnFileSize, lcString, lnIndex, lnTotalBytes LOCAL lnLeft *OUTPUT LOCAL lcOut, m.lcHexLineView m.lcOut = FORCEEXT(cFileName, "hex") m.lnBlockSize = 32 && Размер блока для чтения (заголовок DBF обычно 32 байта) m.lnFile = FOPEN(cFileName, 0) && (Default) Read-only IF m.lnFile = -1 WAIT WINDOW "Ошибка открытия файла" NOWAIT ? "Ошибка открытия файла" RETURN ENDIF * Seek to end of file to determine number of bytes in the file. m.lnFileSize = FSEEK(m.lnFile, 0, 2) && Move pointer to EOF IF m.lnFileSize <= 0 * If file is empty, display an error message. WAIT WINDOW "Этот файл пуст!" NOWAIT ? "Этот файл пуст!" RETURN ENDIF STRTOFILE("", m.lcOut, .F.) = FSEEK(m.lnFile, 0, 0) && Move pointer to BOF m.lnTotalBytes = 0 m.lnHexLine = 0 m.lnLeft = m.lnFileSize DO WHILE m.lnLeft > 0 m.lcString = FREAD(m.lnFile, MIN(m.lnBlockSize, m.lnLeft)) && Чтение блока данных m.lnBytesRead = LEN(m.lcString) IF m.lnBytesRead = 0 EXIT ENDIF m.lnTotalBytes = m.lnTotalBytes + m.lnBytesRead m.lnLeft = m.lnFileSize - m.lnTotalBytes m.lcHexLine = Hex8(m.lnHexLine) + ": " FOR m.lnIndex = 1 TO m.lnBytesRead m.lcChar = SUBSTR(m.lcString, m.lnIndex, 1) m.lcHex = HexWord(ASC(m.lcChar)) m.lcHexLine = m.lcHexLine + m.lcHex IF m.lnIndex = 8 m.lcHexLine = m.lcHexLine + "|" ELSE m.lcHexLine = m.lcHexLine + " " ENDIF ENDFOR m.lcString = STRTRAN(m.lcString, CHR(9), ".") m.lcString = STRTRAN(m.lcString, CHR(10), ".") m.lcString = STRTRAN(m.lcString, CHR(13), ".") STRTOFILE(m.lcHexLine + " | " + m.lcString + CHR(13) + CHR(10), m.lcOut, .T.) m.lnHexLine = m.lnHexLine + 16 ENDDO FCLOSE(m.lnFile) && Закрытие файла MESSAGEBOX("Готово!") RETURN * Функция для преобразования байта в шестнадцатеричное представление FUNCTION HexWord(tnWord, tlZeroX) RETURN (IIF(m.tlZeroX, "0x", "") + STRCONV(CHR(m.tnWord), 15)) ENDFUNC * Функция для преобразования числа в шестнадцатеричное представление с 8 символами FUNCTION Hex8(tnNum) IF m.tnNum = 0 RETURN REPLICATE("0", 8) ENDIF LOCAL lcHex, lnDigit m.lcHex = "" DO WHILE ABS(m.tnNum) > 0 m.lnDigit = BITAND(m.tnNum, 0x0F) m.lcHex = SUBSTR("0123456789ABCDEF", m.lnDigit + 1, 1) + m.lcHex m.tnNum = BITRShift(m.tnNum, 4) ENDDO RETURN PADL(m.lcHex, 8, "0") ENDFUNC