XML是壹種基於文本的數據交換結構,對於字符類型的文本交換非常方便。在實際工作中,我們經常需要通過XML交換二進制格式的圖形和圖像信息數據。介紹了BASE64編碼的原理,並用C語言編寫了DB2的嵌入式存儲過程,實現了文本格式的圖像文件與數據庫內存中二進制BLOB字段的轉換,並提出了壹些性能優化建議。該設計思想和程序可廣泛應用於圖像圖形數據的XML存儲和轉換。
-
回到頂端
用XML存儲圖形和圖像的基本原則
XML作為壹種非常廣泛的數據交換載體,已經廣泛應用於各行各業的數據交換。對於圖形圖像數據的轉換,需要使用Base64編碼將二進制格式的圖形圖像信息轉換為文本格式,然後進行傳輸。
Base64代碼轉換的思想是通過64個ASCII字符代碼對二進制數據進行重新編碼和組合,即將需要轉換的數據每三個字節(24位)進行分組,然後將24位數據按照每組6位進行重新劃分,每組的最高2位用0填充,最終形成壹個完整的8位字節。如果要編碼的數據的字節數不是3的整數倍,則需要在最後壹組數據中填充1到2字節的0字節。例如,我們用BASE64編碼ABC,ABC的編碼值為A(65)、B(66)和C(67)。然後取二進制數A(0100001)B(01000010)C(01000011)並將它們連接起來形成01000000658。8+0,然後以6位為單位將其分成四個數據塊,並在最高位填充兩個0以形成4字節的編碼值(00010000)(00010100)(00001001)(000000001)。然後將4個字節的數據轉換為十進制數(16)(20)(19)(3)。最後,根據BASE64給出的64個基本字符表,找出相應的ASCII字符(Q)(U)(J)(D)。這裏的值實際上是字符表中數據的索引。
BASE64字符表:
abcdefghijklmnopqrstuvwxyzabbcdefghijklmnopqrstuvwxyz 0123456789。
項目的數據交換采用XML作為媒介,XML的結構包括個人基本信息,如姓名、性別、照片等。其中,照片信息是通過BASE64函數轉換的文本數據,圖像和圖形信息通過BASE64轉換形成文本格式的數據類型,然後將相應的數據存儲在XML中,最終形成可交換的文本XML數據結構。
XML的數據結構如下:
& lt?xml版本=“1.0“編碼=“UTF-8“?& gt
& ltHeadInfo & gt
& ltTotalNum & gt10 & lt;TotalNum & gt
& ltTransDate & gt2007-10-18/trans date & gt;
& lt/head info & gt;
& lt數據& gt
& ltName & gt張三
& lt性& gt男性《/Sex & gt;
& lt照片& gt/9j/4a aqskzjrgagabaqaaaqabaad......& lt/Photo & gt;
& lt數據& gt
-
回到頂端
DB2嵌入式C程序中照片數據的實現
該項目要求照片數據可以以二進制BLOB格式存儲在DB2數據庫中。我們使用DATASTAGE加載XML數據,將XML中的姓名和性別等基本數據項加載到相應的字段中,並將基於文本的照片數據加載到CLOB字段中,然後根據BASE64的編碼規則進行反向轉碼。整個數據流如下圖所示:
圖1。照片存儲流程圖
用戶照片的更新數據為每天30萬張,平均每張照片超過32KB。為了獲得最佳的數據庫性能,使用C存儲過程開發了BASE64轉換函數。每次函數讀取存儲在CLOB字段中的文本格式數據時,這些數據都存儲在內存中,並由decode函數在內存中進行代碼轉換,然後存儲在數據庫中。
程序的清單1逐行讀取CLOB字段並調用decode函數進行轉碼;程序的清單2是decode函數的關鍵代碼。完整的程序請參見源代碼下載部分。
清單1。在CLOB中讀取並在BLOB字段中寫入。
EXEC SQL BEGIN DECLARE部分;
SQL類型為CLOB(100K)clobResume;//CLOB結構變量
SQL類型為BLOB(100K)BLOB resume;//BLOB結構變量
sqlint 16 bobind;
sqlint 16 lobind;
sqlint 16 cobind;
sqlint32 idValue
EXEC SQL END DECLARE部分;
int clob 2 bin(void)
{
//聲明SQLCA結構
結構sqlca;
int charNb
int lineNb
長n;
n = 0;
//定義數據庫遊標
EXEC SQL聲明c1遊標並保留
選擇czrkxp_a
FROM CZRK_blob進行更新;
EXEC SQL OPEN c 1;
//活動CLOB字段的信息已經是CLOB字段的大小。
EXEC SQL將c1提取到:clobResume:cobind;
//松散地讀取CLOB字段並調用解碼轉碼函數。
while(sqlca . sqlcode!= 100)
{
if(cobind & lt;0)
{
printf(“指示空LOB。\ n ");
}
其他
{
n++;
decode();//從文本格式到二進制流的代碼轉換功能
printf(“\ n當前行=%ld“,n);
//數據被寫入BLOB字段。
EXEC SQL update czrk _ blob set czrkxp _ blob =:blob sume
其中電流為c 1;;
//提交事務
EXEC SQL提交;
}
EXEC SQL將c1提取到:clobResume:cobind;
}
//關閉光標
EXEC SQL CLOSE c 1;
EXEC SQL提交;
返回0;
}
清單2。文本文件到二進制文件的轉換
無效解碼(無效)
{
無符號字符in【4】,out【3】,v;
int I,len
long j,k;
j =-1;
k = 0;
//將讀取的數據轉換為CLOB結構變量。
while(j & lt;clob resume . length ){
for(len = 0,I = 0;我& lt4 & amp& amp(j & ltclobresume . length);i++ ) {
v = 0;
while((j & lt;clobResume.length)和amp& ampv = = 0 ){
j++;
v =(unsigned char)clobresume . data【j】;
v =(無符號字符)((v & lt43 | | v & gt122) ?0:cd64【v–43】);
如果(五){
v =(無符號字符)((v = =‘$‘)?0:v–61);
}
}
if(j & lt;clob resume . length ){
len++;
如果(五){
in【I】=(無符號字符)(v–1);
}
}
否則{
in【I】= 0;
}
}
if(len ){
解碼塊(輸入,輸出);
//寫入BLOB結構變量。
for(I = 0;我& ltlen–1;i++ ) {
blob resume . data【k】= out【I】;
k++;
}
}
}
blob resume . length = k;
}
-
回到頂端
數據轉換效率和優化建議
該程序運行在IBM P570數據庫服務器上,運行效率非常高,並且已經過幾個數量級的測試。測試的最終平均轉換效率為:每65,438+0,000條數據記錄,轉換效率為55秒,即65,438+0,82條目/秒。值得註意的是,整個轉換過程並不會占用特別多的CPU,主要的性能瓶頸在磁盤陣列。
未來,可以進壹步優化以下方面,以確保更高的程序轉換效率:
1)采用多進程調用的方法獲得更高的並發數;
2)每10次或100次提交事務以減少訪問磁盤的次數;
3)將CLOB和BLOB放在不同的表空間中,並將表空間分布在多個磁盤上以獲得最佳的磁盤訪問速度。