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退出自己的进程时别忘了删除自己产生的数据,这样不仅可以及时清理垃圾数据,还可以节省内存,保持系统的功能稳定。