Мне нужно разделить большой файл DBF с помощью функций php, это означает, что у меня есть, например, 1000 записей, мне нужно создать 2 файла по 500 записей в каждом.
У меня нет расширения dbase и я не могу его установить, поэтому мне приходится работать с основными функциями php. Используя основные fread
Я могу правильно читать и анализировать файл, но когда я пытаюсь написать новый dbf, у меня возникают некоторые проблемы.
Как я понял, файл DBF структурирован в двухстрочный файл: первая строка содержит информацию о файле, информацию заголовка, и это в двоичном виде. Вторая строка содержит данные и представляет собой простой текст. Поэтому я подумал просто написать новый двоичный файл, реплицирующий первую строку и вручную добавив первые записи в первый файл, остальные записи в другой файл.
Это код, который я использую для анализа файла, и он работает хорошо
$fdbf = fopen($_FILES['userfile']['tmp_name'],'r');
$fields = array();
$buf = fread($fdbf,32);
$header=unpack( "VRecordCount/vFirstRecord/vRecordLength", substr($buf,4,8));
$goon = true;
$unpackString='';
while ($goon && !feof($fdbf)) { // read fields:
$buf = fread($fdbf,32);
if (substr($buf,0,1)==chr(13)) {$goon=false;} // end of field list
else {
$field=unpack( "a11fieldname/A1fieldtype/Voffset/Cfieldlen/Cfielddec", substr($buf,0,18));
$unpackString.="A$field[fieldlen]$field[fieldname]/";
array_push($fields, $field);
}
}
fseek($fdbf, 0);
$first_line = fread($fdbf, $header['FirstRecord']+1);
fseek($fdbf, $header['FirstRecord']+1); // move back to the start of the first record (after the field definitions)
first_line
переменная, которая содержит данные заголовка, но когда я пытаюсь записать их в новый файл, происходит что-то неправильное, и строка не записывается точно так, как она была прочитана. Вот код, который я использую для написания:
$handle_log = fopen($new_filename, "wb");
fwrite($handle_log, $first_line, strlen($first_line) );
fwrite($handle_log, $string );
fclose($handle_log);
Я пытался добавить b
значение для fopen
mode
Параметр, как предложено, чтобы открыть его в двоичном виде, я также предложил добавить точно длину строки, чтобы избежать полос некоторых символов, но безуспешно, так как все записанные файлы не в правильном формате DBF. Что я могу сделать, чтобы достичь своей цели?
Как я понял, файл DBF структурирован в двухстрочный файл:
Первая строка содержит информацию о файле, информацию заголовка, и это в двоичном виде.
вторая строка содержит данные, и это обычный текст.
Ну, это немного сложнее, чем это.
Увидеть Вот для полного описания формата файла DBF.
Поэтому было бы лучше, если бы вы могли использовать библиотеку для чтения и записи файлов dbf.
Если вам действительно нужно сделать это самостоятельно, вот самые важные части:
strlen()
будет сканировать данные до первого нулевого байта, который присутствует в этом 32-разрядном целом числе, и вернет неправильное значение.0x20
если запись не удалена, звездочка 0x2A
если запись удалена. (например, если у вас есть 4 поля по 10 байт, длина каждой записи будет 41) — это значение также доступно в заголовке: bytes 10-11 - 16-bit number - Number of bytes in the record. (Least significant byte first)
0x1A
так что вам придется проверить и это.Других решений пока нет …