你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / 数据库开发
3.8 BLOB数据类型在PB开发文件管理系统中的应用
 

一、问题描述

由于笔者所在实验室经常要进行激光雷达实验,实验会产生很多的数据文件,通常会对数据文件进行处理后连带实验结果打包,一般打包后的文件大小在5M20M左右。由于实验产生的文件非常多,不便于管理,故需要开发一个对文件进行管理的数据库管理系统。在权衡了是将文件入库还是将文件的路径入库进行管理的利弊之后,笔者决定实现文件入库,因为这样能保证数据库的安全性及易操作性。而且由于文件较小,读写文件的时间开销在几秒钟内是可以接受的。路径入库虽然节省了读写文件的时间开销,可是数据库却很脆弱,因为路径是很容易被修改或者删除的。笔者在做了详细的需求分析和系统设计之后,决定用PowerBuiler 9.0+ASA8.0来开发这个系统。

 

二、程序实现

1.数据库创建

Sybase Central工具创建一个数据库 LidarData.db,并添加表,表的设计如图1示。


1实验数据文件表的设计

realfile字段在ASA8.0中定义为long binary类型,用来存储BLOB型数据,不同数据库其类型不尽相同,如SQL Server 2000中则可用imagetextntext类型,Oracle 9i则可用Long RawBLOBClobnclob类型。

创建完成后,用ODBC接口连接数据库。

2.主界面与主要功能模块的实现

采用PB提供的各种控件,设计系统的主界面如图2示。

                  


2 系统的主界面

 

1)两个重要函数的创建与实现

在对各功能模块进行代码编写之前,首先要创建两个自定义函数,用于对文件的读操作和写操作,这两个函数分别是f_readfile()f_writefile()。实现代码如下:

//f_readfile()函数声明与实现

Function Name:  f_readfile

Access:   public

Return Type: BLOB

Pass By: Value

Argument Type: string

Argument Name:strfilename  //文件路径传递参数

//该函数实现把二进制文件读入一个BLOB类型变量的功能

//函数体:

int intcount_readfile   // 用于记录文件分块数

int intfileno   // 用于存放文件句柄

int inttemp   // 用于循环记数

long lngfilelength  // 用于存放文件长度

BLOB blobret,blobtemp  // 用于完整和临时分块装载文件数据

lngfilelength=filelength(strfilename)  // 得到文件长度

intcount_readfile=Ceiling(lngfilelength/32765)  //  得到文件块数

intfileno=fileopen(strfilename,streammode!,Read!,Shared!)  // 文件句柄

for inttemp=1 to intcount_readfile   //将文件转换为 BLOB 型数据

fileread(intfileno,blobtemp)    // PowerBuilder中文件读写函数可以自动移动指针

blobret=blobret+blobtemp

next

fileclose(intfileno) // 释放文件资源

return blobret  //返回BLOB类型的数据

//f_writefile()函数声明与实现

Function Name:  f_writefile

Access:   public

Return Type:  boolean

Pass By: Value

Argument Type1:  string  

Argument Type2:  BLOB  

Argument Name1:  strfilename  //文件路径传递

Argument Name2:  blobvariable  //用于写入文件的BLOB类型数据

//该函数实现把BLOB类型变量的值写入文件的功能

//函数体

int intcount_writefile// 用于记录文件分块数

int inttemp   // 用于循环记数

int intfileno

BLOB blobtemp   // 用于临时分块装载 BlOB 数据

intcount_writefile=ceiling(len(blobvariable)/32765)  // 得到 BLOB 数据的长度

//参见附录的len()函数说明

intfileno=fileopen(strfilename,streammode!,write!,LockWrite!,replace!)  // 得到文件句柄

for inttemp=1 to intcount_writefile   // BLOB 型数据转换为文件

blobtemp=blobmid(blobvariable,32765*(inttemp - 1)+1,32765)//参见附录的blobmid()函数说明

filewrite(intfileno,blobtemp)  //blobtemp中的数据写入文件

next

fileclose(intfileno)  // 释放文件资源

return true

2)数据文件导入功能的实现

该模块主要实现实验数据文件以及相关附加属性的入库,界面如图3示:


3数据文件导入功能界面

 

对“确认导入”按钮的Click事件编写代码:

string fileno,filename,datatype,lidarname,getaddress,weather,addition,gettime

BLOB real_file //声明各字段对应的变量名称

int i

fileno=trim(sle_file_no.text)

filename=name

datatype=ddlb_datatype.text

lidarname=trim(ddlb_lidar_name.text)

gettime=trim(sle_get_time.text)

getaddress=trim(ddlb_get_address.text)

weather=trim(ddlb_weather.text)

addition=trim(mle_addition.text) //得到界面所有控件的输入值

real_file=f_readfile(docname) //读取指定文件到real_file,用到了f_readfile函数

 

connect;

  insert into lidardata_tab values(:fileno,:filename,:datatype,:lidarname,:gettime,:getaddress,:weather,:addition,:real_file);

   //将新增的记录插入到数据库的表中

disconnect;

  connect;

 updateblob lidardata_tab set realfile=:real_file where file_no=:fileno;

//real_file插入到记录的BLOB字段中(该步骤不能少,Insert操作并未实现BLOB类型

//的插入)updateblob是对BLOB类型数据的专用修改语句

 string nfilename

 select file_name into :nfilename from lidardata_tab  where file_no=:fileno;

 if nfilename<>"" then

    messagebox("","导入成功!")

else

    messagebox("","导入失败!")

end if

//检验记录导入是否成功完成

w_test.dw_1.settransobject(sqlca)

w_test.dw_1.retrieve()

3)文件导出功能的实现

该功能实现了将选择的记录包含的文件导出到指定路径的功能,并可以打开导出的文件,界面如图4所示。


4 数据文件导出功能界面

对“确认导入”按钮的Click事件编写代码(路径信息赋给一个全局变量)如下:

BLOB outfile

string outfilename,str_filename,str_null

boolean flag,lb_exist

int flag1,flag2

selectblob realfile into :outfile from lidardata_tab where file_no=:selectfile;

//selectfile为一全局变量,存储选定记录的编号

//outfile被赋给选定记录中realfile字段的内容

select file_name into :outfilename from lidardata_tab where file_no=:selectfile;

//得到选定记录中文件名的内容

if FileExists(path+"\"+outfilename) then

 flag2=messagebox("提醒","该路径下已经有一个同名的文件,是否继续导出覆盖该文件?",Question!,YesNO!)

 end if

if flag2=2 then

    return

end if

flag=f_writefile(path+"\"+outfilename,outfile)

if flag=true then

    messagebox("OK","导出完成!")

    flag1=messagebox("???","是否运行已导出的数据文件?",Question!,YesNoCancel! )

end if

   str_filename=trim(sle_1.text)+"\"+outfilename

    lb_exist=FileExists(str_filename)

if(flag1<>1) then

return

end if

if trim(sle_1.text)="" then

messagebox("提示","请选择要打开的数据文件!")

return

    end if

if lb_exist=false then

    messagebox("提示","要打开的数据文件错误或不存在")

    return

end if

ShellExecute(Handle(Parent),str_null,str_filename,str_null,str_null,1)

//调用WinAPI函数运行导出的文件(文件必须要有系统能识别的格式)

三、结语

通过对以上关于BLOB数据类型的使用与函数操作,已经可以把BLOB当作一个普通的数据类型进行操作和管理,不同的是需要编写两个特别的函数f_readfile()f_writefile()。但是不能忽视的是:这种与数据库相关的应用只适合文件较小的时候,因为太大的文件会引起的巨大时间开销。此外,还要特别注意SelectblobUpdateblob语句的用法。

 

 

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089