ID #22934

浅谈VC++ 6.0中临时数据的存储方法

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


2009-02-26 00:00
阅读:
I'm VC , Just U know Y
本站部分文章来源于互联网,版权归原作者所有。

延伸阅读:

使用VC++开发考场随机排座系统

VC++ 2008开发网络百家乐街机游戏(下)

VC++ 2008开发网络百家乐街机游戏(上)

VC++6.0调试篇:远程调试

VC++深入详解:纯虚函数