為了使用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在普通壓縮模...