浅谈VC++ 6.0中临时数据的存储方法
2009-02-26 19:59:49 来源:WEB开发网1 本地文件
一般的说,为了保存计算处理后的结果(该结果不需要永久保存的情况下),我们往往采用生成本地文件的方法进行保存,这样可以将数据处理和结果显示的过程分开。但是对于网络上的其他用户需要访问该文件时,必须在源计算机上共享该文件所在的目录,总之,如果跨网段的机器之间的访问还要保证防火墙的设置允许访问,需要在环境配置允许的情况下使用该方案。另外,保存数据文件时,文件的命名相对比较重要,不同席位间命名的文件应具有唯一性,采用机器名加时间(精确到秒)的方式还是比较安全的。保存文件的类型分很多种,可以是自定义的、txt、xml或者dat类型的都可。下面以比较通用的xml类型的文件为例,介绍其应用方法。假设轨迹数据的所有记录放在列表m_listctrlgj中,从列表中取出记录数据保存在文件cpu120071226155022.xml中。(m_listctrlgj是附件中给出的类CSortListCtrl类的对象变量)
表1: xx系统的飞行轨迹数据
序号 | 经度 | 纬度 | 高度(米) |
1 | 105°14′09″ | 35°50′15″ | 3500 |
2 | 105°39′02″ | 35°27′37″ | 3500 |
3 | 106°03′54″ | 35°04′42″ | 3500 |
4 | 107°00′46″ | 34°41′29″ | 3500 |
代码如下:
CString xh,jdstr,wdstr,gdstr,redstr;
_bstr_t xht,jdstrt,wdstrt,gdstrt;
CMarkup xml;//封装了xml格式文件操作的类,附件中给出了类文件
int itemnum=m_listctrlgj.GetItemCount();
if (itemnum>0)
{//获取轨迹内容
xml.AddElem( _T("ydgj") );
redstr="";
for(int i=0;i<itemnum;i++)
{
xh=m_listctrlgj.GetItemText(i,0);
jdstr=m_listctrlgj.GetItemText(i,1); //获取经度
wdstr=m_listctrlgj.GetItemText(i,2); //获取纬度
gdstr=m_listctrlgj.GetItemText(i,3); //获取高度
xht=_com_util::ConvertStringToBSTR(xh); //取出轨迹数据放进缓冲区中
jdstrt=_com_util::ConvertStringToBSTR(jdstr);
wdstrt=_com_util::ConvertStringToBSTR(wdstr);
gdstrt=_com_util::ConvertStringToBSTR(gdstr);
if (i==0)
{
xml.AddChildElem( _T("ITEM") );
xml.IntoElem();
}
else
{
xml.AddElem( _T("ITEM"));
}
xml.AddChildElem( _T("xh"),xht);
xml.AddChildElem( _T("jd"),jdstrt);
xml.AddChildElem( _T("wd"),wdstrt);
xml.AddChildElem( _T("gd"),gdstrt);
}//保存完毕
}
读取信息部分的代码如下:
redstr=xml.GetDoc();
int totalnum=redstr.GetLength();
char* pbuf=new char[totalnum];
CFile f1;
CString flname="cpu120071226155022.xml";
if( !f1.Open(flname,CFile::modeCreate|CFile::modeWrite))
{
}
f1.Write(redstr,totalnum);
f1.Close();
2 临时数据表
当对计算的结果需要各种查询统计的时候,文件格式的结果处理起来比较麻烦。这时比较好的方法我们利用临时数据表。
为了建立临时表,Oracle数据库系统中可使用create global temporary table命令。在建立临时表时,可以指定它是否在整个会话期间都存在(利用on commit preserve rows字句),或者在事务处理完成时是否删除它的行(利用on commit delete rows子句)。
与永久表不同,在建立临时表时不会自动分配空间。表的空间是在插入行时动态地分配的。
在建立这种临时结果时,如果是在局域网的环境下,即几个客户端共用同一数据库的情况下,结果数据的保存便会出现混乱,所以我们仿照C#.net中的用法,在临时数据表中建立一个用户标识,根据用户的ID号来保存计算的结果数据。
举例:
create global temporary table TEMP_GJTABLE
(
YHID VARCHAR2(17),
GJXH NUMBER(2),
JD VARCHAR2(13),
WD VARCHAR2(12),
GD NUMBER(5,1)
)
on commit preserve rows;
以表1中的数据为例,将轨迹数据进行保存时,首先提取数据库中最大的YHID,当前的YHID为库中最大值加1, adoSet为指向TEMP_GJTABLE表的记录集。示例如下所示:
int yhid;
CString xh,jdstr,wdstr,gdstr,yhidstr;
if (!adoSet.IsEOF())
{
yhid=adoSet.GetInt("max(yhid)");
yhid+=1;
}
else
yhid=0;
adoSet.Close();
yhidstr.Format("%d",yhid);
int itemnum=m_listctrlgj.GetItemCount();
if (itemnum>0)
{
for(int i=0;i<itemnum;i++)
{
xh=m_listctrlgj.GetItemText(i,0);
jdstr=m_listctrlgj.GetItemText(i,1); //获取经度
wdstr=m_listctrlgj.GetItemText(i,2); //获取纬度
gdstr=m_listctrlgj.GetItemText(i,3); //获取高度
sqlstrcap.Format(“insert into ppgl_temp_gjtable values('%s',%s,'%s ','%s ',%s”,yhidstr,xh,jdstr,wdstr,gdstr); //插入纪录
try
{
adoConn->Execute(sqlstrcap);
adoConn->Execute("commit");
}
catch (...)
{
}
}
}
当对中间结果进行统计查询等操作时,用文件存储的数据,操作起来比较麻烦,速度比较慢,从而影响系统性能,但是利用数据库的强大查询引擎功能,采用临时数据表就会大大的提高操作的速度。
3 对象数组
对于本地用户来说,使用对象数组来处理数据速度是最快的,在C#开发的web应用服务系统中,网络上来保存共享的临时数据的效果也不错。下面我们仍以上述的移动轨迹的保存法来举例说明对象数组的应用。temp_gjobject是定义用来存放轨迹对象的CObject的派生类。这里仍以表1中的数据为例。
1) 定义temp_gjobject类。
class temp_gjobject : public CObject
{
public:
temp_gjobject(){;}
public:
CString yhid;
int gjxh;
CString jd;
CString wd;
double gd;
};
2) 添加数据
在应用时只要定义Ctemp_gjobjectArray类型的变量,就可以向对象数组中保存数据了。然后定义Ctemp_gjobjectArray的公用变量,记住在添加时首先要判断m_gjarray中保存的yhid的最大值。代码如下:
typedef CTypedPtrArray<CObArray,temp_gjobject*> Ctemp_gjobjectArray;
Ctemp_gjobjectArray m_gjarray;
CString yhid;
int count=m_gjarray.GetSize();
int maxyhid=0;
Cjscs* m_gjobj=new temp_gjobject ();//定义类变量
if(count>0)
{
for(int i=0;i<count;i++)
{
m_gjobj=m_gjarray.GetAt(i);
yhid=m_gjobj.yhid;
if(atoi(yhid)> maxyhid)
maxyhid=atoi(yhid);
}
}
else
maxyhid=0;
yhid.Format(“%d”,maxyhid+1);
CString xh,jdstr,wdstr,gdstr;
int itemnum=m_listctrlgj.GetItemCount();
if (itemnum>0)
{
for(int i=0;i<itemnum;i++)
{
xh=m_listctrlgj.GetItemText(i,0);
jdstr=m_listctrlgj.GetItemText(i,1); //获取经度
wdstr=m_listctrlgj.GetItemText(i,2); //获取纬度
gdstr=m_listctrlgj.GetItemText(i,3); //获取高度
m_gjobj ->yhid=yhid;
m_gjobj ->gjxh=xh;
m_gjobj >jd=jdstr;
m_gjobj ->wd=wdstr;
m_gjobj >gd=gdstr;
m_gjarray.Add(m_gjobj);
}
}
通过以上两步就完成了数据的保存。
4 结论
综上所述,在实际应用中可以灵活的选择数据存储的方法,在有些情况下上述三种情况可以通用。但是有一点需要注意,对于网络中共用开辟的保存容器时,在每个yhid退出自己的进程时别忘了删除自己产生的数据,这样不仅可以及时清理垃圾数据,还可以节省内存,保持系统的功能稳定。
更多精彩
赞助商链接