如何利用Pro C直接讀取dbf檔案

2021-05-09 17:38:33 字數 4903 閱讀 4863

為了使用c語言程式設計直接讀取dbf檔案,需要了解dbf檔案的二進位制檔案格式,下面給出簡要的說明。

表檔案由頭記錄及資料記錄組成。頭記錄定義該錶的結構幷包含與表相關的其他資訊。頭記錄由檔案位置 0 開始。資料記錄1緊接在頭記錄之後(連續的位元組),包含欄位中實際的文字。

記錄的長度(以位元組為單位)等於所有字段定義的長度之和。表檔案中儲存整數時低位位元組在前。

1.表頭記錄的結構:

位元組偏移 說明

0 檔案型別

0x02foxbase

0x03foxbase+/dbase iii plus,無備註

0x30visual foxpro

0x43dbase iv sql 表檔案,無備註

0x63dbase iv sql 系統檔案,無備註

0x83foxbase+/dbase iii plus,有備註

0x8bdbase iv 有備註

0xcbdbase iv sql 表檔案,有備註

0xf5foxpro 2.x(或更早版本)有備註

0xfbfoxbase

1 - 3 最近一次更新的時間(yymmdd)

4 - 7 檔案中的記錄數目

8 - 9 第乙個資料記錄的位置

10 - 11 每個資料記錄的長度(包括刪除標記)

12 - 27 保留

28 表的標記

0x01具有 .cdx 結構的檔案

0x02檔案包含備註。

0x04檔案是資料庫(.dbc)

請注意,這個位元組可以包含任何上面值的和。例如,0x03 表明表具有結構化.cdx和乙個備註字段。

29 **頁標記

30 - 31 保留,包含 0x00

32 - n 字段子記錄

欄位的數目決定了字段子記錄的數目。表中每個欄位都對應乙個字段子記錄。

n+1 頭記錄終止符(0x0d),n+2 到 n+264 此範圍內的 263 個位元組包含後鏈資訊(相關資料庫 (.dbc) 的相對路徑)。如果第乙個位元組為 0x00,則該檔案不與資料庫關聯。因此資料庫檔案本身總是包含 0x00。

1 頭記錄中的第 8 到第 9 個位元組指示資料檔案中資料的起始位置。資料記錄從 除標記位元組開始。如果此位元組為 ascii 空格 (0x20),該記錄沒有刪除標記, 如果第一位元組為星號 (0x2a),該記錄有刪除標記。在標記之後是字段記錄中所命名各字段中的資料

2.字段子記錄結構

位元組偏移 說明

0 - 10 欄位名(最多 10 個字元 -若少於 10 則用空字元 (0x00) 填充)

11 字段型別

c-字元型

y-貨幣型

n-數值型

f-浮點型

d-日期型

t-日期時間型

b-雙精度型

i-整型

l-邏輯型

m-備註型

g-通用型

c-字元型(二進位制)

m-備註型(二進位制)

p-型

12 - 15 記錄中該字段的偏移量

16 字段長度(以位元組為單位)

17 小數字數

18 字段標記

0x01系統列(使用者不可見)

0x02可儲存 null 值的列

0x04二進位制列(只適於字元型和備註型)

19 - 32 保留

格式儲存的檔案標頭:

支援 null 值

日期時間型、貨幣型及雙精度型資料

字元欄位和備註字段標記為二進位制

在資料庫 (.dbc) 檔案中新增表

提示 可以使用下面的公式求出表檔案中字段的數目:(x - 296/32) 公式中,x 表示第乙個記錄的位置(表頭記錄的第 8 到第 9 個位元組),296 表示 263(後鏈資訊)+ 1(頭記錄終止符)+ 32(第乙個字段子記錄),32 是字段子記錄的長度。

因為dbf檔案的記錄在檔案資料部分,都是用ascii碼形式存放的,所以只要讀出檔案頭和字段型別描述區的內容,就可以直接讀取dbf檔案中的每條記錄,dbf檔案頭結構和字段型別描述結構用c語言表示如下:

struct dbf_head ;

struct field_element;

需要注意的是,輸入的dbf檔案是foxpro 2.5 for dos/windows的版本,檔案頭中表示記錄數等內容的unsigned long和unsigned short欄位,定址順序是從高位到低位;而c程式在hp-ux作業系統下編譯時,hp伺服器使用的risc cpu的定址順序與intel x86系列cpu的定址順序相反,是從低位到高位,故程式中需要將讀取的unsigned long和unsigned short進行反轉操作,可以使用位操作程式設計實現:

void revert_unsigned_short(unsigned short *a)

void revert_unsigned_long(unsigned long *a)

根據上面對dbf檔案格式的分析,使用pro*c程式設計,即可以很方便地實現直接讀取dbf檔案的功能。具體源**附錄如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define nfields 5

#define true 1

#define false 0

/* dbf檔案頭結構 */

struct dbf_head ;

/* dbf欄位描述結構 */

struct field_element;

char *dbf_fields_name[nfields]=;

/* 全域性變數 */

struct dbf_head file_head;

struct field_element *fields;

int *length;

unsigned int *offset;

/*函式原形宣告*/

void revert_unsigned_short(unsigned short *a);

void revert_unsigned_int(unsigned int *a);

void revert_unsigned_short(unsigned short *a)

void revert_unsigned_int(unsigned int *a)

int main(int argc,char *argv)

fseek(fp_dat,0l,seek_set);

fread((void*)&file_head,sizeof(struct dbf_head),1,fp_dat);

revert_unsigned_int(&file_head.no_recs);

revert_unsigned_short(&file_head.head_len);

revert_unsigned_short(&file_head.rec_len);

fields_count=(file_head.head_len-sizeof(struct dbf_head)-1)/sizeof(struct field_element);

if((fields=(struct field_element*)malloc(sizeof(struct field_element)*fields_count))==null)

if((buffer=(char*)malloc(sizeof(char)*file_head.rec_len))==null)

if((allspace=(char*)malloc(sizeof(char)*file_head.rec_len))==null)

else

fread((void*)fields,sizeof(struct field_element),fields_count,fp_dat);

for(i=0;i< td>

revert_unsigned_int(&fields[i].offset);

fields[0].offset=1;

for(i=1;i< td>

fields[i].offset=fields[i-1].offset+(unsigned short)fields[i-1].field_length;

length=(int*)malloc(sizeof(int)*fields_count);

offset=(unsigned int*)malloc(sizeof(unsigned int)*fields_count);

if(length==null||offset==null)

for(i=0;i< td>

if(!matched)

else

matched=false;} }

fseek(fp_dat,(long)file_head.head_len,seek_set);

for(counts=0;counts< td>

fread((void*)buffer,(int)file_head.rec_len-1,1,fp_dat);

buffer[file_head.rec_len]='/0';

if(strcmp(buffer,allspace)==0) /*去掉全為空格的記錄行

continue;

/* 進一步處理buffer中資料 */

}fclose(fp_dat);

free(buffer);

free(allspace);

free(offset);

free(length);

return 0;

}

如何利用 Async IO 讀取告警規則?

在大多數情況下,io 操作都是乙個耗時的過程,尤其在流計算中,如果在具體的運算元裡面還有和第三方外部系統 比如資料庫 redis hbase 等儲存系統 做互動,比如在乙個 mapfunction 中每來一條資料就要去查詢 mysql 中某張表的資料,然後跟查詢出來的資料做關聯 同步互動 查詢請求到...

如何利用python讀取micaps檔案詳解

最近用程式設計處理檔案挺多的,matlab用得比較熟,但還是想用python來寫寫,fortran就不用了。所用到的資料如下圖,前面4行是說明,實際要用的資料是第5行開始。一共是有29 53個點,每一組就有53個資料,一共是有29組。下面就是操作了 匯入所需的庫 import numpy 開啟 mi...

利用AS3類直接讀取Rar檔案中的swf檔案

名稱 rarextractor rar檔案解壓器 url 作用 最初的目的是想實現flash檔案直接讀取rar裡的資源,這樣在外部檔案較多的情況下,可以打包到rar檔案裡再load進來。不過由於水平有限,並沒有研究出rar的解壓演算法。而swf檔案預設採用zlib壓縮方式後,winrar在普通壓縮模...