Рейтинг:
14
Jochen Arndt
Насколько я понимаю, у вас есть файл с заголовком, за которым следует несколько наборов записей. Затем вы должны соответствующим образом скорректировать смещение при обработке ваших данных:
$header = unpack ($header_format, $data);
// Note that your code used header_format here wrongly
$numRecords = $header['L# of Records'];
// Assuming these are what the name indicates
$offset = $header['SHeader Size'];
$recordSize = $header['SRecord Size'];
for ($i = 0; $i < $numRecords; $i++)
{
$record = unpack ($record_format, $data, $offset);
$offset += $recordSize;
}
Для этого необходимо настроить
unpack()
правильно отформатируйте строки, чтобы они соответствовали данным в файле. То
CTime
поле, например, выглядит подозрительно, потому что я понятия не имею, как значение времени может храниться в 8 битах.
[РЕДАКТИРОВАТЬ]
Если существует несколько пакетов, начинающихся с заголовка, вы должны поместить вышеизложенное во внешний цикл:
$offset = 0;
$data_len = strlen($data);
while ($offset < $data_len)
{
// Get package header
$header = unpack ($header_format, $data, $offset);
// Number of records in this package
$numRecords = $header['L# of Records'];
// Size of each record for this packet
$recordSize = $header['SRecord Size'];
// Adjust offset to point to first record of this packet
$offset += $header['SHeader Size'];
// Process records of this packet
for ($i = 0; $i < $numRecords; $i++)
{
$record = unpack ($record_format, $data, $offset);
// Adjust offset to point to next record of this packet
$offset += $recordSize;
}
// $offset points to next package header if not at end of data
}
[/РЕДАКТИРОВАТЬ]
Patrice T
Это файл .dbf.
ОП счастливо перепутал набор записей с тем, что на самом деле является заголовками полей.
Первый заголовок начинается со смещения 32, и каждый заголовок имеет размер 32.
Jochen Arndt
Это было не совсем понятно для меня, потому что предоставленные строки формата не соответствовали структурам DBF.
Но мое решение все еще показывает, как итеративно корректировать смещение по мере необходимости.
Более важно то:
Похоже, что он использовал символы типа данных DBF в своих строках формата PHP unpack вместо использования соответствующих идентификаторов PHP.
Member 13967442
Этот файл не является файлом .dbf, это файл .bin с каждым пакетом, имеющим размер заголовка 18. и "CTime/" является неправильным "dTime", так как это временная метка
Patrice T
Откуда взялась эта линия ?
"# Получить верхнюю часть заголовка файла dbf"
Member 13967442
извините это ошибка
Jochen Arndt
Ваш набор записей на самом деле имеет размер 28 и заголовок 12 с одним байтом для поля времени. Временная метка может иметь 4 или 8 байт, что в общей сложности составляет 15 или 19.
Member 13967442
запись имеет размер 30, а заголовок-18, Вот как я ее посчитал
Member 13967442
$заголовок = распаковать ($header_format, $данных);
$numRecords = $header['L# записей'];
для ($i = 0; i < $numRecords; $i++)
{
$запись = распаковать ($record_format, $данных $я);
}
Я считаю, что приведенный выше код может распаковать первый пакет, как мне сделать это для следующего пакета до конца файла
Jochen Arndt
C = 1 байт, S = 2 байта, L = 4 байта, I = зависит, Q = 8 байт, f = 4 байта (одинарная точность)
Jochen Arndt
Как и в моем решении:
Третий параметр задает смещение в данные.
Так что это должно быть установлено соответствующим образом (размер заголовка для первой записи, а затем увеличен на размер записи).
Member 13967442
а как насчет чтения следующего заголовка пакета?
Jochen Arndt
Я тебя не понимаю.
Если структура файла такая, как предполагается в моем решении, то у вас есть заголовок и наборы записей. Затем вы получаете доступ к заголовку сначала с нулевым смещением, а затем к наборам записей с соответствующим смещением.
Member 13967442
я хочу сказать, что вышеприведенное решение работает только для первого пакета,
$numRecords = $header['L# of Records']; // значение в $numRecords-это количество записей в первом первом пакете. как сделать цикл, чтобы получить $numRecords в заголовочном файле каждого пакета.
Jochen Arndt
На этот вопрос можно ответить только зная файловую структуру, которую я не знаю.
Мое решение заключается в следующем
- один заголовок, содержащий информацию о # следующих записей
- 1. набор записей
- 2. набор записей
- ...
- количество наборов - 1 набор
Если файловая структура отличается, Вы должны сообщить нам ее структуру.
Member 13967442
один заголовок содержит информацию о записях#, которые необходимо распаковать для данного конкретного пакета. и поэтому информация в каждом заголовке различна. например, один пакет может иметь 2 записи или следующий пакет может быть 5...в соответствии с чтением в каждом заголовке $['L# записей'];
Jochen Arndt
Затем вы должны написать внешний цикл вокруг моего решения. Я его обновлю.
Рейтинг:
1
Patrice T
Цитата:
Мне нужно распаковать оставшуюся часть пакета.
Я думаю, что ваша проблема заключается в том, что вы всегда распаковываете файл в начале
unpack ("$record_format", $data)
вместо позиции того, что вы хотите распаковать.
Начало заголовка файла со смещением 0
Первое поле заголовка по смещению 32
Второе поле заголовка по смещению 64
...
Но
$данные вот и весь файл.
.dbf - Википедия[^]
[Обновление]
- Нет!
Это начало цикла в 32 и это не header_format:
for ($offset = 0; $offset < strlen ($data); $offset += 32) {
$unpackeddata= unpack ("@$offset/$header_format", $data);
print "";
print_r ($unpackeddata);
print "";
}
[Обновление]
Все, что касается .dbf в решении, неверно, потому что
# Get the top of the dbf file header
в исходном коде это тоже неправильно.
Patrice T
Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.