Форум » [x]Harbour » Опять о формате dbase » Ответить

Опять о формате dbase

Pasha: Этот вопрос время от времени здесь поднимается. Есть такой формат visual dbase, который харбор не поддерживает. Обычно 1-й байт заголовка файла - 0x04 Вот, к примеру, его описание и обсуждение в harbour mail list: [url=http://www.mail-archive.com/harbour@harbour-project.org/msg24578.html]click here[/url] Кто-нибудь читал такие файлы любыми средствами ? Я думаю, можно сделать хотя бы чтение/запись таких файлов через usrrdd, без поддержки индексов. Но прежде чем делать, решил спросить

Ответов - 21, стр: 1 2 All

Pasha: Поскольку мне надо было прочитать сабж быстро, сделал класс DBASE, пока только для чтения Спецификация класса: CLASS DBase DATA nHandle DATA cHeader DATA nType DATA nFileSize DATA nRecCount DATA nHdrLen DATA nRecLen DATA nFieldCnt DATA aStruct DATA nRecNo DATA cRecord DATA lBof DATA lEof METHOD New(cName) CONSTRUCTOR METHOD Defaults() METHOD First() METHOD Last() METHOD Next() METHOD Skip(nSkip) METHOD Goto(nRec) METHOD FieldPos( cField ) METHOD Deleted() METHOD Close() DESTRUCTOR Finalize() ERROR HANDLER OnError() ENDCLASS

Andrey: А как вообще определить - что файл DBF ? Я понимаю, что по первому байту можно CHR(3) . Но так может быть что другой файл начинается с CHR(3).... Есть ли какая проверка на принадлежность файла к классу DBF и по типам DBF ?

Pasha: В первом байте dbf значение может быть не только 3 см. функцию hb_dbfReadDBHeader в source\rdd\dbf1.c Это то, что харбор поддерживает, а могут быть и другие значения, тот же формат dbase А как определить... да, точно, по расширению файла же можно ! Можно правда еще выполнить простейшую проверку: размер заголовка плюс размер записи*к-во записей должен быть равным размеру файла. Если это так - это наверняка дбф


Andrey: Pasha пишет: А как определить... да, точно, по расширению файла же можно ! Если бы ! В РКЦ Донецка умники сидят.... Лицевой счет абонента типа: 8а498/35, 8а330/25, 19/89, 82/3, 8а605/46, 6а308/30, 8а271/115 ..... А оплату жильцов передают в файлах с расширениями "фиг поймешь", типа: 68411010.87d 68411010.c6d 68411010.f5d 68411010.h9d 68411010.lcd 68411010.scd 68411011.8cd 68411011.cad 68411011.i9d 68411011.o6d 68411011.r7d 68411011.u4d 68411012.f7d и т.д. А заодно еще передают текстовые файлы с почти такими же расширениями: 6841d711.c0p 6841d711.ps 6841d71a.ps 6841d721.c0p 6841d721.o0p 6841d721.ps 6841d72a.ps Мне то нетрудно быстренько вручную их раскидать.... А за моей программой девушки работают. Попробуй им объясни какие файлы куда переписывать... Удавись... Pasha пишет: Можно правда еще выполнить простейшую проверку: размер заголовка плюс размер записи*к-во записей должен быть равным размеру файла. Если это так - это наверняка дбф А алгоритм можно ?

Pasha: Алгоритм это слишком громко для такой проверки 4 байта с 4-го - это к-во записей размер заголовка - 2 байта с 8-го размер записи - 2 байта с 10-го считать эти значения через fopen - fread, получить размер файла, и выполнить проверку

fil: А что, ошбку при открыти обработать низя ? Тож можно определить DBF не DBF

Pasha: Andrey пишет: В РКЦ Донецка умники сидят.... я плачу квартплату по твоей программе ? интересно...

Andrey: Pasha пишет: я плачу квартплату по твоей программе ? интересно... Нет не по моей. Я от них данные беру для своей программы, кто и сколько заплатил за домофон. База хорошая Firebird 1.5 , а вот реализация....

Pasha: Понятно. У меня домофона нет

petr707: [pre2] // ..... nerr=0 cerr="" get_dbfpar(filename,,,,,,@nerr,@cerr) if nerr#0 // "Некорректная БД" endif //........ Function get_dbfpar(fn,f_size,nbyte,last_rec,rec_size,of_set,nerr,cerr) // параметры DBF static arr_err:={; {0,"<Нет ошибки > "} ,; //1 {1,"<Не файл БД > "} ,; //2 {2,"<Неверный размер БД > "} ,; //3 {4,"<Нет доступа Read+Sh> "} ,; //4 {5,"<Аттрибут READONLY > "} ,; //5 {6,"<Дата БД больше тек.> "} ; //6 } Local ret:=.t.,s,nHandle LOCAL nCurrent,fattr:=0 Local sag:=chr(03),ierr:=1 f_size :=0 nbyte :=0 last_rec:=0 rec_size:=0 of_set :=0 DO WHILE .t. nerr :=arr_err[1,1]; cerr := arr_err[1,2] s:=space(32) nHandle:=fopen(fn,FO_READ+FO_SHARED) if ( ret:=(nHandle>=0) ) nCurrent := FSEEK( nHandle, 0, FS_RELATIVE ) // Get file position // Get file length nbyte := FSEEK( nHandle, 0, FS_END ) // размер файла FSEEK( nHandle, nCurrent ) // Reset file position fread(nHandle,@s,32) sag:= asc(substr(s,1,1)) if !(sag=3.or.sag=131) // БД или БД с мемо ret:=.f.;ierr:=2 nerr:=arr_err[ierr,1]; cerr := arr_err[ierr,2] endif last_rec:= ; 256*256*(; 256*asc(substr(s,8,1)) ; +asc(substr(s,7,1)) ; )+; 256*asc(substr(s,6,1)) ; +asc(substr(s,5,1)) rec_size:=; // размер записи 256*asc(substr(s,12,1)) ; +asc(substr(s,11,1)) of_set:=; // смещение - размер заголовка 256*asc(substr(s,10,1)) ; +asc(substr(s, 9,1)) f_size:= last_rec*rec_size+of_set+1 // размер базы if abs(f_size-nbyte)>rec_size // несовпадение размера базы и файла ret:=.f.;ierr:=3 nerr:=arr_err[ierr,1]; cerr := arr_err[ierr,2] endif if f_size > nbyte+1 ret:=.f.;ierr:=2 nerr:=arr_err[ierr,1]; cerr := arr_err[ierr,2] endif FCLOSE(nHandle) if ret if ISBIT(FILEATTR(fn),1)// Readonly ret:=.f.;ierr:=5 nerr:=arr_err[ierr,1]; cerr := arr_err[ierr,2] EXIT endif if FILEDATE(fn) > date() ret:=.f.;ierr:=6 nerr:=arr_err[ierr,1]; cerr := arr_err[ierr,2] endif endif else //nHandle<0 ret:=.f.;ierr:=4 nerr:=arr_err[ierr,1]; cerr := arr_err[ierr,2] endif EXIT ENDDO return ret [/pre2]

Andrey: Спасибо БОЛЬШОЕ petr707 ! Думаю не только мне пригодиться !

mshep: Добрый день! Заказали мне формировать вых.файлы в формате dBase IV: клиенту необходимо сохранить в формате DBF dBASE IV и документы загружаются в систему "Клиент-Банк" Присланные файлы были сохранены в формате DBF dBASE III К стыду признаю, что не знаю как сие сделать средствами Clipper/Harbour. Как при создании (открытии) указать, что файл dBase IV??

Dima: mshep http://articles.org.ru/docum/dbfall.php http://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTM#Table_2 Там разница в заголовке , посмотри чем они отличаются и потом через Fwrite преврати базу в нужный формат. mshep пишет: Как при создании (открытии) указать, что файл dBase IV?? Скорее всего ни как.

petr707: Смотрите описание в dbinfo.ch RDDI_TABLETYPE Лучше иметь образцы файлов, тогда проще, как пример ниже - функция создания некоторого типа таблицы, похоже Visual_foxpro (без претензии на универсальность) Правда, с костылем - прямая запись в заголовок Далее такую таблицу удается заполнить обычными средствами - append ,append from .. .... Function FoxDBCREATE(cfile,arr_str) Local ret:=.t.,f_hand:=0,sf1:=chr(3),sf2:=chr(0x1A) #include "dbinfo.ch" hb_rddinfo(RDDI_TABLETYPE,DB_DBF_VFP) DBCREATE(cfile ,arr_str) f_hand:=FOPEN(cfile,FO_READWRITE) if f_hand>0 FSEEK(f_hand, 0,0)// FWRITE(f_hand,sf1,1) FSEEK(f_hand,-1,2)// FWRITE(f_hand,sf2,1) FCLOSE(f_hand) endif hb_rddinfo(RDDI_TABLETYPE,DB_DBF_STD) return ret

mshep: Спасибо. уже прогуглил, поплакал.... Не думал, что так все запущено....... Еще не знаю, как после преобразования они будут открываться в клиппере (фоксовские например в автомате при открытии в клиппере преобразуются в клипперовские) и как проверять, что я буду отправлять в банк...... Есть еще добрые люди где-то сверху, которые помогают тем, кому делать нечего! ))))

mshep: Опять дедушка тупит что-то…… (((( Посмотрел описание заголовка dbf (http://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTM например) и посмотрел файл якобы dBase IV, что мне ребятишки из банка любезно прислали как образец, разница его с моим - в 29-м байте заголовка “26” у них стоит (у меня – “00”, а по http://articles.org.ru/docum/dbfall.php это – зарезервированная обл.), и в описаниях полей после типа поля (т.е. начиная с 12 байта) стоят значения какие-то (если верить http://articles.org.ru/docum/dbfall.php, это – “Адрес данных поля (ссылка на память, а не на диск)” . Что это за ссылка???? Интересное наблюдение: когда я из программы физически ставлю “26” в заголовок в свой сформированный файл, потом открываю его в DBFnavigator и там сохраняю как dBase IV, мои ручные “26” она зануляет (т е так же как и якобы в dBase IV должно быть), но в описаниях полей что-то после 11 файла что-то лепит, причем то же, что и в банковских файлах. Резюмируя, возникают вопросы: 1) Что за байда “26” в 29 байте заголовка (есть в образце, что мне дали, но не создает его DBFнавигатор при сохранении файла в формате dBase IV). Имеет ли это отношение к dBase IV вообще? 2) Что записывается в описаниях полей после типа поля? - “Адрес данных поля (ссылка на память, а не на диск)” . Для текущ.файла я, понятно, слижу эти цифорки из образца, что мне дали, проблема – если потом другой файл создавать надо будет. Путано наверно дедушка написал, да может поймет кто и поможет дотошно….

mshep: P.S. Присмотрелся - понял: просто смещение это начала поля относительно начала записи...... Видно, совсем иной механизм пробега по файлу в dBase IV.... Так что вопрос 2) отпадает. Первый вопрос, хоть и не актуален для жизни, остается, ибо непонимаемое вселяет смятение в души.....

petr707: 29 0x1D 1 Идентификатор кодовой страницы файла (dBASE IV, Visual FoxPro, XBase). См. табл 9. Не нужно открывать такую таблицу в Clipper, он удаляет этот байт ( укорачивает заголовок) Открывайте Fox'ом

mshep: Пасибки!! Только что зашел отрапортовать, что закрыл вопрос - нашел по др ccылке - Russian OEM = “26”. Так что все уже почти OK. То что клиппер приводит к св виду - знаю, вопросы все снялись, осталось только подумать, как клиентов убедить, что по формированию файла для банка справка с него им не нужна..... Мои извинения что хлопот доставил - не самые удачные ссылки по описанию структуры сначала открыл.... И тогда еще доп.вопрос: есть какой-то dbf-браузер, который однозначно бы сказал, какой формат файла? (DBFнавигвтор просто тупо якобы переписывает в выбираемом формате, а в каком формате был данный ему файл - не выдает

mshep: Возможно, кому-то еще потребуется копаться с dBase IV. Из своих исследований: Никакого лейбла или картинки, что это именно dBase IV, в заголовке файла нет. Отличия: a) по другому как-то пишется 1б в “Дата последней модификации в виде ГГММДД” (год), но это не влияет; б) в дескрипторе поля после типа поля в dBaseIV пишется его смешение относительно начала записи (в dBaseIII – “00”), длины поля нет ни в III, ни в IV, хотя по описанию в “Энциклопедии юных сурков”: 11 0x0B 1 Тип поля. См. табл 7 12 0x0C 4 Зарезервировано 16 0x10 1 Полная длина поля Непонятка получается. ((( в) В III в нач.инф.части стоит 0D, в IV его нет. г) DbfNavigator при преобразовании файла III в IV удаляет в конце “1A” (но это кажется уже погрешность его самого). Правил файл на физуровне, с заголовком быстро получилось, а в записях в длинах вечно путался. Потом выключил вторую извилину у себя в голове и в файле IV тупо удалил руками в текст.редакторе (не ZAP) всю инф. часть включая хвостик 0D001A после этого в программе файл открылся, записался и уже откликался на кличку “dBase IV”. Слишком просто и скучно ((((( На этом и покончил. Но желание разобраться на будущее осталось…

mshep: Опять с непонятками столкнулся. DBF, сохданный в старом добром Clippere год в заголовке файла указывает как “10” (16), а созданный в Hdrboure (CODEPAGE "RU866" VIA "DBFNTX") - как “74” (116). При создании файла в Clippere в заголовке после типа поля в 4 зарезерв.байта (по описанию) пишется какая-то шелупень, в Harbour – нули проставляются. При записи в Harboure в клипперовский dbf запись года в заголовке не меняется (на тек.день, не знаю, как при модификации в разные дни, не пробовал еще), а шелупень - когда вычищается, когда нет.... (((



полная версия страницы