Хотя это и не PHP, VFP основан на ссылках, основанных на 1, и я думаю, что PHP основан на нулях, поэтому вам придется расшифровать и соответствующим образом настроить, но это работает, и, надеюсь, вы сможете опубликовать свою версию этой части, когда закончите.
FILETOSTR() в VFP откроет файл и прочитает все содержимое в одну переменную памяти в виде строки символов — все управляющие клавиши, символы старшего байта и т. д. без изменений. Вам, вероятно, придется полагаться на FOPEN(), FSEEK(), FCLOSE() и т. д.
MemoTest.FPT был моей таблицей/файлом для примера fpt1 = FILETOSTR("MEMOTEST.FPT")
Во-первых, вам нужно будет определить MEMO BLOCK SIZE, использованный при создании файла. Обычно это будет 64 БАЙТА, но по ссылке, которую вы указали в своем посте.
Позиции заголовка 6-7 определяют размер (VFP, позиции 7 и 8). Первый байт является старшим
nBlockSize = ASC( SUBSTR( fpt1, 7, 1 )) * 256 + ASC( SUBSTR( fpt1, 8, 1 ))
Теперь о ваших индивидуальных записях. Везде, где в вашей структуре DBF есть memo FIELD (и у вас может быть много на одну структуру записи), там будет 4 байта. В поле ЗАПИСЬ он идентифицирует «блок» в файле заметок, в котором хранится содержимое.
MemoBytes = 4 байта в указанном вами местоположении поля. Они будут храниться как ASCII от 0 до 255. Это поле хранится с ПЕРВЫМ байтом в качестве младшего и 4-м байтом в виде 256 ^ 3 = 16777216. Первый когда-либо использованный «Блок» будет начинаться со смещения позиции 512 в соответствии со спецификацией файла memo .fpt, которую занимает заголовок. позиции 0-511.
Итак, если ваше первое поле memo имеет содержимое «8000», где 8 — это фактический 0x08, а не номер «8», который равен 0x38, а нули равны 0x00.
YourMemoField = "8000" (фактически используйте ascii, но для удобочитаемости показывает шестнадцатеричное ожидаемое значение)
First Byte is ASCII value * 1 ( 256 ^ 0 )
Second Byte is ASCII value * 256 (256 ^ 1)
Third Byte is ASCII value * 65536 (256 ^ 2)
Fourth Byte is ASCII value * 16777216 (256 ^ 3)
nMemoBlock = byte1 + ( byte2 * 256 ) + ( byte3 * 65536 ) + ( byte4 * 16777216 )
Теперь вам нужно использовать FSEEK() для
FSEEK( handle, nMemoBlock * nBlockSize +1 )
для первого байта блока, который вы ищете. Это будет указывать на заголовок BLOCK. В этом случае, согласно спецификации, первые 4 байта идентифицируют ПОДПИСЬ блока, вторые 4 байта — это длина содержимого. Для этих двух байтов сначала хранятся HIGH-BYTE.
Из вашего FSEEK() это ОБРАТНАЯ ВЕРСИЯ nMemoBlock выше со старшим байтом. "Byte1-4" здесь из вашей позиции FSEEK()
nSignature = ( byte1 * 16777216 ) + ( byte2 * 65536 ) + ( byte3 * 256 ) + byte4
nMemoLength = ( byte5 * 16777216 ) + ( byte6 * 65536 ) + ( byte7 * 256 ) + byte8
Теперь FSEEK() до 9-го байта (1-й фактический символ данных ПОСЛЕ 8 байтов заголовка, который вы только что прочитали для подписи и длины заметки). Это начало ваших данных.
А теперь прочтите остальную часть...
FSEEK() +9 characters to new position
cFinalMemoData = FREAD( handle, nMemoLength )
Я знаю, что это не идеально, как и PHP-скрипт, но достаточно псевдокода о том, как хранятся вещи, и, надеюсь, вам ХОРОШО на вашем пути.
Опять же, ПОЖАЛУЙСТА, примите во внимание, когда вы выполняете процесс отладки, чтобы обеспечить базовое смещение 0 или 1. Чтобы упростить и протестировать это, я создал простой .DBF с двумя полями... символьное поле и поле для заметок, добавил несколько записей и некоторый базовый контент для подтверждения всего контента, позиций и т. д.
person
DRapp
schedule
22.12.2009