文章目录

  • 1.分区预警信号数据:strstr,UpdateStr
    • 1.1 数据说明:.txt后缀可改为.csv后缀
    • 1.2 建表入表:站点代码改为街道代码,站点名称改为街道名称
  • 2.台风(热带气旋)数据:SplitBuffer,InsertTable
    • 2.1 数据说明:头记录,实况路径
    • 2.2 建表入表:AddTime
  • 3.全国天气预报数据:文件名的信息不用关心
  • 4.酸雨数据:一和二行
  • 5.能见度数据:无分隔符
  • 6.计算:gunzip,imp
  • 7.数据交换:数据导出为文件,数据文件推送

1.分区预警信号数据:strstr,UpdateStr

1.1 数据说明:.txt后缀可改为.csv后缀

下面是excel软件打开.txt文件(以逗号分隔)。

如下是xml标准格式,前后加< data >标签,每行后加< end1/>,只有标准格式才能用浏览器打开显示。


下面为说明文档:

1.2 建表入表:站点代码改为街道代码,站点名称改为街道名称


// psignallog.cpp封成类
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _psignallog();
connection conn;
void EXIT(int sig);
int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理分区预警信号发布日志,并保存到数据库的T_SIGNALLOG表中。\n");printf("/oracle/htidc/shqx/bin/psignallog 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/oracle/htidc/shqx/bin/psignallog /oracle/data/shqx/sdata/wpfiles /oracle/log/shqx/psignallog.log shqx/pwdidc@snorcl11g_128 10\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");//1111111111111111111111111111111111111111111111111111111111  while (true){// logfile.Write("开始扫描目录。\n");    if (Dir.OpenDir(argv[1],"WP20*.DTB",1000,true,true)==false){ // 扫描数据文件存放的目录,只匹配"WP20*.DTB"logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}while (true)  // 逐个处理目录中的数据文件{if (Dir.ReadDir()==false) break;  if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}// logfile.Write("连接数据库成功。\n");}  logfile.Write("开始处理文件%s...",Dir.m_FileName);        if (_psignallog()==false)  {logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//111111111111111111111111111111111111111111111111111111
bool _psignallog()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}CSIGNALLOG SIGNALLOG(&conn,&logfile);char strBuffer[301]; // 读取文件中的每一行记录,写入数据库的表中while (true){memset(strBuffer,0,sizeof(strBuffer));    if (File.Fgets(strBuffer,300,true)==false) break;  // 从文件中获取一行记录// 每行预警信号发布的记录的最后都是用"000="结束的。不会得到第一,二行和最后一行if (strstr(strBuffer,"000=")==0) continue;UpdateStr(strBuffer,"  "," ",true);  // 把内容中的两个空格替换成一个空格// logfile.Write("%s\n",strBuffer);    // 把用逗号分隔的记录拆分到结构体中if (SIGNALLOG.SplitBuffer(strBuffer)==false) { logfile.Write("%s\n",strBuffer); continue; }// 把vsignallog容器中的值更新到T_SIGNALDATA表中。long rc=SIGNALLOG.InsertTable();// 只要不是数据库session的错误,程序就继续。if ( (rc>=3113) && (rc<=3115) ) return false;if (rc != 0) { logfile.Write("%s\n",strBuffer); continue; }}  conn.commit(); // 提交事务  File.CloseAndRemove(); // 关闭文件指针,并删除文件logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",SIGNALLOG.totalcount,SIGNALLOG.insertcount,SIGNALLOG.updatecount,SIGNALLOG.invalidcount);return true;
}

关于_shqx.h(增加了struct st_signallog结构体)和_shqx.cpp见文章:https://blog.csdn.net/weixin_43435675/article/details/103476761

WP…0510.DTB时间是05:10:00下面是加了8小时。

2.台风(热带气旋)数据:SplitBuffer,InsertTable

2.1 数据说明:头记录,实况路径

第一行第四个开始:开始依次气旋序号cyclone(001),国内编号num(1801),热带气旋终结标志ws(0),每行路径间隔小时数hours(6),热带气旋的英文名称t_name(BOLAVEN),数据集形成的日期datasettime(20190319)。

第二行第一个开始:YYYY年MM月DD日HH时ddatetime(世界时2018021000),强度标记h_level(1),纬度lat(84),经度lon(1435),中心最低气压pres(1008),2分钟平均近中心最大风速wnd(13),(2分钟平均风速owd)。

1.头记录(第一行)格式如下:

2.实况路径(第二行往下)(不是预报路径)数据记录格式如下:

2.2 建表入表:AddTime

// typthoon.cpp
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _typthon(); //处理数据文件
connection conn;
void EXIT(int sig);int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理分区预警信号发布日志,并保存到数据库的T_SIGNALLOG表中。\n");printf("/oracle/htidc/shqx/bin/typthon 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/oracle/htidc/shqx/bin/typthon /oracle/data/shqx/sdata/typthon /oracle/log/shqx/typthon.log shqx/pwdidc@snorcl11g_128 10\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");//11111111111111111111111111111111111111111111111111111111while (true){logfile.Write("开始扫描目录。\n");// 扫描数据文件存放的目录,只匹配"CH20*.DTB"if (Dir.OpenDir(argv[1],"CH*.TXT",1000,true,true)==false){logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}// 逐个处理目录中的数据文件while (true){if (Dir.ReadDir()==false) break;  if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}logfile.Write("连接数据库成功。\n");}  logfile.Write("开始处理文件%s...",Dir.m_FileName);  if (_typthon()==false)  //处理数据文件{logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//111111111111111111111111111111111111111111111111111
bool _typthon()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}CTYPTHOON TYPTHON(&conn,&logfile);// 读取文件中的每一行记录// 写入数据库的表中char strBuffer[301];while (true){memset(strBuffer,0,sizeof(strBuffer));    if (File.Fgets(strBuffer,300,true)==false) break; //从文件中获取一行记录UpdateStr(strBuffer,"  "," ",true);  //把内容中的两个空格替换成一个空格// logfile.Write("%s\n",strBuffer);    // 把用逗号分隔的记录拆分到结构体中if (TYPTHON.SplitBuffer(strBuffer)==false) { logfile.Write("%s拆分失败\n",strBuffer); continue; }    long rc=TYPTHON.InsertTable(); // 把vsignallog容器中的值更新到T_SIGNALDATA表中if ( (rc>=3113) && (rc<=3115) ) return false; // 只要不是数据库session的错误,程序就继续if (rc != 0) { logfile.Write("%s\n",strBuffer); continue; }}conn.commit();File.CloseAndRemove();logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",TYPTHON.totalcount,TYPTHON.insertcount,TYPTHON.updatecount,TYPTHON.invalidcount);return true;
}
//_shqx.h
#ifndef _SHQX_H
#define _SHQX_H
#include "_public.h"
#include "_ooci.h"struct st_typthoon1  //实况路径
{ char ddatetime[21];   // YYYY年, MM月, DD日,HH时(世界时);char h_level[2];      //强度标记double lat;          // 纬度double lon;          // 经度char pres[2];     //中心最低气压(hPa);int  wnd;     //2分钟平均近中心最大风速(MSW, m/s)int  owd;     //2分钟平均风速(m/s)int t_no;  //自定义台风编号,从第0个开始
};
struct st_typthoon  //头记录
{char cyclone[5];       //气旋序号char num[5];        //国内编号char ws[2];            //热带气旋终结标志char hours[2];         //每行路径间隔小时数, 目前均为6(小时);char t_name[30];         //热带气旋的英文名称, 名称后加 “(-1)n” 表示副中心及其序号;char datasettime[21];  //数据集形成的日期
};class CTYPTHOON
{public:int totalcount,insertcount,updatecount,invalidcount;  // 记录总数据、插入数、更新数、无效记录数。int c;//个数struct st_typthon m_sttypthon;struct st_typthon1 m_sttypthon1;vector<struct st_typthon> vtypthon;   // 容器存放一个文件的全部记录CTYPTHON(connection *conn,CLogFile *logfile);~CTYPTHON();void initdata();  // 数据初始化connection *m_conn;CLogFile   *m_logfile;int iccount;sqlstatement stmtsel,stmtins,stmtupt;// 把记录拆分到vsignallog容器中。bool SplitBuffer(const char *strBuffer);// 把vsignallog容器中的值更新到T_SIGNALDATA表中。long InsertTable();
};
#endif
//_shqx.cpp
#include "_shqx.h"CTYPTHON::CTYPTHON(connection *conn,CLogFile *logfile)
{initdata();m_conn=conn; m_logfile=logfile;
}
void CTYPTHON::initdata()
{totalcount=insertcount=updatecount=invalidcount=0;m_conn=0; m_logfile=0;memset(&m_sttypthon,0,sizeof(struct st_typthon));memset(&m_sttypthon1,0,sizeof(struct st_typthon1));
}
CTYPTHON::~CTYPTHON()
{}//111111111111111111111111111111111111111111111111111111111111111111111
bool CTYPTHON::SplitBuffer(const char *strBuffer)
{ //把用逗号分隔的记录拆分到m_sttypthon结构中totalcount++;
//  memset(&m_sttypthon1,0,sizeof(struct st_typthon));CCmdStr CmdStr;CmdStr.SplitToCmd(strBuffer," ",true);c= CmdStr.CmdCount();if(CmdStr.CmdCount()==9){memset(&m_sttypthon,0,sizeof(struct st_typthon));CmdStr.GetValue(3,m_sttypthon.cyclone,4); CmdStr.GetValue(4,m_sttypthon.num,4); CmdStr.GetValue(5,m_sttypthon.ws,1); CmdStr.GetValue(6,m_sttypthon.hours,1); CmdStr.GetValue(7,m_sttypthon.t_name,29); CmdStr.GetValue(8,m_sttypthon.datasettime,19); }if (CmdStr.CmdCount()==6){memset(&m_sttypthon1,0,sizeof(struct st_typthon1));CmdStr.GetValue(0,m_sttypthon1.ddatetime,10); // 数据时间:格式yyyymmddhh24strcat(m_sttypthon1.ddatetime,"0000");AddTime(m_sttypthon1.ddatetime,m_sttypthon1.ddatetime,8*60*60,"yyyy-mm-dd hh24:mi:ss");CmdStr.GetValue(1,m_sttypthon1.h_level,1);double dtmp=0;int ii=0;CmdStr.GetValue(2,&dtmp); m_sttypthon1.lat=dtmp; CmdStr.GetValue(3,&dtmp); m_sttypthon1.lon=dtmp;  CmdStr.GetValue(4,m_sttypthon1.pres,1);CmdStr.GetValue(5,&ii); m_sttypthon1.wnd=ii;CmdStr.GetValue(5,&ii); m_sttypthon1.owd=ii;}//判断是不是同一个台风,根据2分钟平均风速*30*60  每小时小于20公里来判断// if (CmdStr.CmdCount()!=6 && CmdStr.CmdCount()!=9) //{ invalidcount++; return false; }if(CmdStr.CmdCount()==9) {invalidcount++;}return true;
}//1111111111111111111111111111111111111111111111111111111111111111
long CTYPTHON::InsertTable()
{if (stmtsel.m_state==0){stmtsel.connect(m_conn);stmtsel.prepare("select count(*) from T_TYPTHON where cyclone=:1 and t_name=:2 and ddatetime=to_date(:3,'yyyy-mm-dd hh24:mi:ss')");stmtsel.bindin( 1, m_sttypthon.cyclone,4);stmtsel.bindin( 2, m_sttypthon.t_name,29);stmtsel.bindin( 3, m_sttypthon1.ddatetime,20);stmtsel.bindout(1,&iccount);//m_logfile->Write("\nt_name==%s\n,ddatetime==%s",m_sttypthon.t_name,m_sttypthon1.ddatetime); }if (stmtins.m_state==0){stmtins.connect(m_conn);stmtins.prepare("insert into T_TYPTHON(cyclone,num,ws,hours,t_name,datasettime,ddatetime,h_level,lat,lon,pres,wnd,owd,crttime,keyid) values(:1,:2,:3,:4,:5,to_date(:6,'yyyy-mm-dd'),to_date(:7,'yyyy-mm-dd hh24:mi:ss'),:8,:9,:10,:11,:12,:13,sysdate,SEQ_TYPTHON.nextval)");stmtins.bindin( 1, m_sttypthon.cyclone,4);stmtins.bindin( 2, m_sttypthon.num,4);stmtins.bindin( 3, m_sttypthon.ws,1);stmtins.bindin( 4, m_sttypthon.hours,4);stmtins.bindin( 5, m_sttypthon.t_name,29);stmtins.bindin( 6, m_sttypthon.datasettime,20);stmtins.bindin( 7, m_sttypthon1.ddatetime,20);stmtins.bindin( 8, m_sttypthon1.h_level,1);stmtins.bindin( 9, &m_sttypthon1.lat);stmtins.bindin( 10, &m_sttypthon1.lon);stmtins.bindin( 11, m_sttypthon1.pres,1);stmtins.bindin( 12, &m_sttypthon1.wnd);stmtins.bindin( 13, &m_sttypthon1.owd);//m_logfile->Write(" 插入%s,%s,%s,%s,%s,%s,%s,%s,%lf,%lf,%s,%d,%d\n",m_sttypthon.cyclone,m_sttypthon.num,m_sttypthon.ws,m_sttypthon.hours,m_sttypthon.t_name,m_sttypthon.datasettime,m_sttypthon1.ddatetime,m_sttypthon1.h_level,m_sttypthon1.lat,m_sttypthon1.lon,m_sttypthon1.pres,m_sttypthon1.wnd,m_sttypthon1.owd);}if (stmtupt.m_state==0){stmtupt.connect(m_conn);stmtupt.prepare("update T_TYPTHON set ddatetime=to_date(:1,'yyyy-mm-dd hh24:mi:ss'),h_level=:2,lat=:3,lon=:4,pres=:5,owd=:6,wnd=:7 where cyclone=:8 and t_name=:9 and ddatetime=to_date(:10,'yyyy-mm-dd hh24:mi:ss')");stmtupt.bindin( 1, m_sttypthon1.ddatetime,20);stmtupt.bindin( 2, m_sttypthon1.h_level,1);stmtupt.bindin( 3, &m_sttypthon1.lat);stmtupt.bindin( 4, &m_sttypthon1.lon);stmtupt.bindin( 5, m_sttypthon1.pres,1);stmtupt.bindin( 6, &m_sttypthon1.owd);stmtupt.bindin( 7, &m_sttypthon1.wnd);stmtupt.bindin( 8, m_sttypthon.cyclone,4);stmtupt.bindin( 9, m_sttypthon.t_name,29);stmtupt.bindin( 10, m_sttypthon1.ddatetime,20);}if (stmtsel.execute() != 0){invalidcount++; m_logfile->Write("stmtsel.execute() failed.\n%s\n%s\n",stmtsel.m_sql,stmtsel.m_cda.message); //m_logfile->Write("%s,abcderf=%s",m_sttypthon.datasettime,m_sttypthon1.ddatetime);//m_logfile->Write("%s,==%s",m_sttypthon.t_name,m_sttypthon1.ddatetime); return stmtsel.m_cda.rc;}  iccount=0;stmtsel.next();   if(c==6){  //必须是正确的数据才进行插入和查询if (iccount>0) {   if (stmtupt.execute() != 0)   //执行更新的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("stmtupt.execute() failed.\n%s\n%s\n",stmtupt.m_sql,stmtupt.m_cda.message);return stmtupt.m_cda.rc;}updatecount++;}else{    if (stmtins.execute() != 0)  //执行插入的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("stmtins.execute() failed.\n%s\n%s\n",stmtins.m_sql,stmtins.m_cda.message);return stmtins.m_cda.rc;}insertcount++;}}return 0;
}

3.全国天气预报数据:文件名的信息不用关心



如下从第四行product,foretime【世界时需加8小时,今天夜间就是今晚20点到明早08天,明天白天就是明天08点到晚上20点,2个时间段】,起报时间为00+8=08时,3为8+3=11点,6为8+6=14点…,168小时7天,遇到999替换为空。第六行obtid站号P5599,21为下面有21行。第七行依次:时次,温度,相对湿度…



//forecast.cpp
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _forecast();
connection conn;
//void EXIT(int sig);
int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理分区预警信号发布日志,并保存到数据库的T_FORECAST表中。\n");printf("/oracle/htidc/shqx/bin/forecast 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/oracle/htidc/shqx/bin/forecast /oracle/data/shqx/sdata/forecast /oracle/log/shqx/forecast.log shqx/pwdidc@snorcl11g_128 10\n");return -1;}// CloseIOAndSignal();// signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");while (true){logfile.Write("开始扫描目录。\n");    if (Dir.OpenDir(argv[1],"Z_*.TXT",1000,true,true)==false){ // 扫描数据文件存放的目录,只匹配"Z_*.DTB"logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}//1111111111111111111111111111111111111111111111111111111111111    while (true)  // 逐个处理目录中的数据文件{if (Dir.ReadDir()==false) break;  if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}logfile.Write("连接数据库成功。\n");}  logfile.Write("开始处理文件%s...",Dir.m_FileName);  if (_forecast()==false)  //处理数据文件{logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//11111111111111111111111111111111111111111111111111111111111
bool _forecast()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}CFORECAST FORECAST(&conn,&logfile);char strBuffer[301];while (true){memset(strBuffer,0,sizeof(strBuffer));    if (File.Fgets(strBuffer,300,true)==false) break;  //从文件中获取一行记录UpdateStr(strBuffer,"  "," ",true);   //把内容中的两个空格替换成一个空格// logfile.Write("%s\n",strBuffer);    // 把用逗号分隔的记录拆分到结构体中if (FORECAST.SplitBuffer(strBuffer)==false) { logfile.Write("%s拆分失败\n",strBuffer); continue; }    long rc=FORECAST.InsertTable(); //把vsignallog容器中的值更新到T_SIGNALDATA表中if ( (rc>=3113) && (rc<=3115) ) return false;  //只要不是数据库session的错误,程序就继续if (rc != 0) { logfile.Write("插入失败%s\n",strBuffer); continue; }}conn.commit();File.CloseAndRemove();logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",FORECAST.totalcount,FORECAST.insertcount,FORECAST.updatecount,FORECAST.invalidcount);return true;
}
//_shqx.h
#ifndef _SHQX_H
#define _SHQX_H
#include "_public.h"
#include "_ooci.h"
struct st_forecast
{char product[6];                                   char foretime[20];
};
struct st_forecast1
{char obtid[6];
};
struct st_forecast2
{char sx[4];                                        char wd[6];                   char csd[6];            char wind[6];                  char speed[6];                 char pressure[6];              char p[6]; char cloud[6];                 char lcloud[6];                char weather[6];               char vis[6];                   char ht[6];                    char lt[6];                    char maxsd[6];                 char minsd[6];                 char p2[6];                    char p1[6];                    char c2[6];                    char c1[6];                    char weather1[6];             char wind1[6];                 char speed1[6];
};
class CFORECAST
{public:int totalcount,insertcount,updatecount,invalidcount;  // 记录总数据、插入数、更新数、无效记录数。struct st_forecast m_stforecast;struct st_forecast1 m_stforecast1;struct st_forecast2 m_stforecast2;CFORECAST(connection *conn,CLogFile *logfile);~CFORECAST();void initdata();  // 数据初始化connection *m_conn;CLogFile   *m_logfile;int iccount;sqlstatement stmtsel,stmtins,stmtupt;bool SplitBuffer(const char *strBuffer); // 把记录拆分到vsignallog容器中。  long InsertTable(); // 把vsignallog容器中的值更新到T_SIGNALDATA表中。
};
#endif
//_shqx.cpp
#include "_shqx.h"
CFORECAST::CFORECAST(connection *conn,CLogFile *logfile)
{initdata();m_conn=conn; m_logfile=logfile;
}
void CFORECAST::initdata()
{totalcount=insertcount=updatecount=invalidcount=0;m_conn=0; m_logfile=0;memset(&m_stforecast,0,sizeof(struct st_forecast));memset(&m_stforecast1,0,sizeof(struct st_forecast1));memset(&m_stforecast2,0,sizeof(struct st_forecast2));
}
CFORECAST::~CFORECAST()
{}//1111111111111111111111111111111111111111把用逗号分隔的记录拆分到m_stforecast结构中
bool CFORECAST::SplitBuffer(const char *strBuffer)
{totalcount++;CCmdStr CmdStr;CmdStr.SplitToCmd(strBuffer," ",true);c = CmdStr.CmdCount();if(CmdStr.CmdCount()==2){memset(&m_stforecast,0,sizeof(struct st_forecast));CmdStr.GetValue(0,m_stforecast.product,5);CmdStr.GetValue(1,m_stforecast.foretime,10);strcat(m_stforecast.foretime,"0000");AddTime(m_stforecast.foretime,m_stforecast.foretime,8*60*60,"yyyy-mm-dd hh24:mi:ss");}if(CmdStr.CmdCount()==6){memset(&m_stforecast1,0,sizeof(struct st_forecast1));CmdStr.GetValue(0,m_stforecast1.obtid,5); }if (CmdStr.CmdCount()==22){memset(&m_stforecast2,0,sizeof(struct st_forecast2));CmdStr.GetValue(0,m_stforecast2.sx,3);CmdStr.GetValue(1,m_stforecast2.wd,5); CmdStr.GetValue(2,m_stforecast2.csd,5); CmdStr.GetValue(3,m_stforecast2.wind,5);CmdStr.GetValue(4,m_stforecast2.speed,5);CmdStr.GetValue(5,m_stforecast2.pressure,5);CmdStr.GetValue(6,m_stforecast2.p,5); CmdStr.GetValue(7,m_stforecast2.cloud,5);CmdStr.GetValue(8,m_stforecast2.lcloud,5); CmdStr.GetValue(9,m_stforecast2.weather,5);CmdStr.GetValue(10,m_stforecast2.vis,5);CmdStr.GetValue(11,m_stforecast2.ht,5);CmdStr.GetValue(12,m_stforecast2.lt,5);CmdStr.GetValue(13,m_stforecast2.maxsd,5);CmdStr.GetValue(14,m_stforecast2.minsd,5);CmdStr.GetValue(15,m_stforecast2.p2,5);CmdStr.GetValue(16,m_stforecast2.p1,5);CmdStr.GetValue(17,m_stforecast2.c2,5);CmdStr.GetValue(18,m_stforecast2.c1,5);CmdStr.GetValue(19,m_stforecast2.weather1,5); CmdStr.GetValue(20,m_stforecast2.wind1,5); CmdStr.GetValue(21,m_stforecast2.speed1,5);}return true;
}//11111111111111111111111111111111把m_stforecast结构中的值更新到T_FORECAST表中
long CFORECAST::InsertTable()
{if (stmtsel.m_state==0){stmtsel.connect(m_conn);stmtsel.prepare("select count(*) from T_FORECAST where product=:1 and foretime=to_date(:2,'yyyy-mm-dd hh24:mi:ss') and obtid=:3 and sx=:4");stmtsel.bindin(1,m_stforecast.product,5);stmtsel.bindin(2,m_stforecast.foretime,19);stmtsel.bindin(3,m_stforecast1.obtid,5);stmtsel.bindin(4,m_stforecast2.sx,3);stmtsel.bindout(1,&iccount);}if (stmtins.m_state==0){stmtins.connect(m_conn);stmtins.prepare("insert into T_FORECAST values(:1,to_date(:2,'yyyy-mm-dd hh24:mi:ss'),:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22,:23,:24,:25,SEQ_FORECAST.nextval,sysdate)");stmtins.bindin( 1, m_stforecast.product,5);stmtins.bindin( 2, m_stforecast.foretime,19);stmtins.bindin( 3, m_stforecast1.obtid,5);stmtins.bindin( 4, m_stforecast2.sx,3);stmtins.bindin( 5, m_stforecast2.wd,5);stmtins.bindin( 6, m_stforecast2.csd,5);stmtins.bindin( 7, m_stforecast2.wind,5);stmtins.bindin( 8, m_stforecast2.speed,5);stmtins.bindin( 9, m_stforecast2.pressure,5);stmtins.bindin( 10,m_stforecast2.p,5);stmtins.bindin( 11,m_stforecast2.cloud,5);stmtins.bindin( 12,m_stforecast2.lcloud,5);stmtins.bindin( 13,m_stforecast2.weather,5);stmtins.bindin( 14,m_stforecast2.vis,5);stmtins.bindin( 15,m_stforecast2.ht,5);stmtins.bindin( 16,m_stforecast2.lt,5);stmtins.bindin( 17,m_stforecast2.maxsd,5);stmtins.bindin( 18,m_stforecast2.minsd,5);stmtins.bindin( 19,m_stforecast2.p2,5);stmtins.bindin( 20,m_stforecast2.p1,5);stmtins.bindin( 21,m_stforecast2.c2,5);stmtins.bindin( 22,m_stforecast2.c1,5);stmtins.bindin( 23,m_stforecast2.weather1,5);stmtins.bindin( 24,m_stforecast2.wind1,5);stmtins.bindin( 25,m_stforecast2.speed1,5);  }if (stmtupt.m_state==0){stmtupt.connect(m_conn);stmtupt.prepare("update T_FORECAST set sx:1,wd=:2,csd=:3,wind=:4,speed=:5 where product=:6 and foretime=to_date(:7,'yyyy-mm-dd hh24:mi:ss') and obtid=:8 and sx=:9");stmtupt.bindin( 1,m_stforecast2.sx,3);stmtupt.bindin( 2,m_stforecast2.wd,5);stmtupt.bindin( 3,m_stforecast2.csd,5);stmtupt.bindin( 4,m_stforecast2.wind,5);stmtupt.bindin( 5,m_stforecast2.speed,5);stmtupt.bindin( 6,m_stforecast.product,5);stmtupt.bindin( 7,m_stforecast.foretime,19);stmtupt.bindin( 8,m_stforecast1.obtid,5);stmtupt.bindin( 9,m_stforecast2.sx,3);}if (stmtsel.execute() != 0){//m_logfile->Write("%s,%s",m_stforecast.foretime,m_stforecast2.sx);invalidcount++; m_logfile->Write("stmtsel.execute() failed.\n%s\n%s\n",stmtsel.m_sql,stmtsel.m_cda.message); return stmtsel.m_cda.rc;}  iccount=0;stmtsel.next();if (c!=22){invalidcount++;} if(c==22){if (iccount>0) {if (stmtupt.execute() != 0){invalidcount++; m_logfile->Write("stmtupt.execute() failed.\n%s\n%s\n",stmtupt.m_sql,stmtupt.m_cda.message);return stmtupt.m_cda.rc;}updatecount++;}else{   if (stmtins.execute() != 0)  //执行插入的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("\n%s,m_stforecast.foretime=%s,%s,%s,%lf,%s\n",m_stforecast.product,m_stforecast.foretime,m_stforecast1.obtid,m_stforecast2.sx,m_stforecast2.wd,m_stforecast2.csd);m_logfile->Write("stmtins.execute() failed.\n%s\n%s\n",stmtins.m_sql,stmtins.m_cda.message);return stmtins.m_cda.rc;}insertcount++;}}return 0;
}

4.酸雨数据:一和二行





//adid.cpp
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _adid();
connection conn;
void EXIT(int sig);int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理分区预警信号发布日志,并保存到数据库的T_ADID表中。\n");printf("/oracle/htidc/shqx/bin/adid 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/oracle/htidc/shqx/bin/adid /oracle/data/shqx/sdata/adid /oracle/log/shqx/adid.log shqx/pwdidc@snorcl11g_128 10\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");while (true){logfile.Write("开始扫描目录。\n");   if (Dir.OpenDir(argv[1],"Z_*.TXT",1000,true,true)==false){ // 扫描数据文件存放的目录,只匹配"Z_*.DTB"logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}//1111111111111111111111111111111111111111111111111111111while (true){if (Dir.ReadDir()==false) break;  if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}logfile.Write("连接数据库成功。\n");}logfile.Write("开始处理文件%s...",Dir.m_FileName);  if (_adid()==false) {logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//1111111111111111111111111111111111111111111111111
bool _adid()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}CADID ADID(&conn,&logfile);char strBuffer[301];while (true){memset(strBuffer,0,sizeof(strBuffer));    if (File.Fgets(strBuffer,300,true)==false) break; // 从文件中获取一行记录UpdateStr(strBuffer,"  "," ",true);  // 把内容中的两个空格替换成一个空格// logfile.Write("%s\n",strBuffer);    // 把用逗号分隔的记录拆分到结构体中if (ADID.SplitBuffer(strBuffer)==false) { logfile.Write("%s拆分失败\n",strBuffer); continue; }    long rc=ADID.InsertTable(); // 把vsignallog容器中的值更新到T_SIGNALDATA表中if ( (rc>=3113) && (rc<=3115) ) return false; //只要不是数据库session的错误,程序就继续if (rc != 0) { logfile.Write("插入失败%s\n",strBuffer); continue; }}conn.commit();File.CloseAndRemove();logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",ADID.totalcount,ADID.insertcount,ADID.updatecount,ADID.invalidcount);return true;
}
//_shqx.h
#ifndef _SHQX_H
#define _SHQX_H
#include "_public.h"
#include "_ooci.h"
struct st_adid
{char obtid[6];char lat[7];char lon[7];char height[7];char mode[2];
};
struct st_adid1
{char adidate[20];char astart[7];char aend[7];char r[6];char t[4];char ph1[5];char ph2[5];char ph3[5];char ph_av[5];char w[4];char s[4];char pheno[9];
};
#endif
//_shqx.cpp
#include "_shqx.h"
bool CADID::SplitBuffer(const char *strBuffer)
{totalcount++;CCmdStr CmdStr;CmdStr.SplitToCmd(strBuffer," ",true);c = CmdStr.CmdCount();if(CmdStr.CmdCount()==5){memset(&m_stadid,0,sizeof(struct st_adid));CmdStr.GetValue(0,m_stadid.obtid,5); CmdStr.GetValue(1,m_stadid.lat,5); CmdStr.GetValue(2,m_stadid.lon,6); CmdStr.GetValue(3,m_stadid.height,6);CmdStr.GetValue(4,m_stadid.mode,1);}if (CmdStr.CmdCount()==28){memset(&m_stadid1,0,sizeof(struct st_adid1));CmdStr.GetValue(0,m_stadid1.adidate,16);AddTime(m_stadid1.adidate,m_stadid1.adidate,8*60*60,"yyyy-mm-dd hh24:mi:ss");CmdStr.GetValue(1,m_stadid1.astart,6); CmdStr.GetValue(2,m_stadid1.aend,6); CmdStr.GetValue(3,m_stadid1.r,5);CmdStr.GetValue(4,m_stadid1.t,3);CmdStr.GetValue(5,m_stadid1.ph1,4);CmdStr.GetValue(6,m_stadid1.ph2,4); CmdStr.GetValue(7,m_stadid1.ph3,4);CmdStr.GetValue(8,m_stadid1.ph_av,4); char strtemp[11];memset(strtemp,0,sizeof(strtemp));CmdStr.GetValue(22,strtemp,6);m_stadid1.w[0]=strtemp[0];m_stadid1.w[1]=strtemp[1];m_stadid1.w[2]=strtemp[2];m_stadid1.s[0]=strtemp[3];m_stadid1.s[1]=strtemp[4];m_stadid1.s[2]=strtemp[5];CmdStr.GetValue(26,m_stadid1.pheno,8);}return true;
}//1111111111111111111111111111111111111111111111111111
long CADID::InsertTable()
{if (stmtsel.m_state==0){stmtsel.connect(m_conn);stmtsel.prepare("select count(*) from T_ADID where obtid=:1 and adidate=to_date(:2,'yyyy-mm-dd hh24:mi:ss')");stmtsel.bindin(1,m_stadid.obtid,5);stmtsel.bindin(2,m_stadid1.adidate,19);stmtsel.bindout(1,&iccount);}if (stmtins.m_state==0){stmtins.connect(m_conn);stmtins.prepare("insert into T_ADID values(:1,:2,:3,:4,:5,to_date(:6,'yyyy-mm-dd hh24:mi:ss'),:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,sysdate,SEQ_ADID.nextval)");stmtins.bindin( 1, m_stadid.obtid,5);stmtins.bindin( 2, m_stadid.lat,5);stmtins.bindin( 3, m_stadid.lon,6);stmtins.bindin( 4, m_stadid.height,6);stmtins.bindin( 5, m_stadid.mode,1);stmtins.bindin( 6, m_stadid1.adidate,19);stmtins.bindin( 7, m_stadid1.astart,6);stmtins.bindin( 8, m_stadid1.aend,6);stmtins.bindin( 9, m_stadid1.r,5);stmtins.bindin( 10,m_stadid1.t,3);stmtins.bindin( 11,m_stadid1.ph1,4);stmtins.bindin( 12,m_stadid1.ph2,4);stmtins.bindin( 13,m_stadid1.ph3,4);stmtins.bindin( 14,m_stadid1.ph_av,4);stmtins.bindin( 15,m_stadid1.w,3);stmtins.bindin( 16,m_stadid1.s,3);stmtins.bindin( 17,m_stadid1.pheno,8);}if (stmtupt.m_state==0){stmtupt.connect(m_conn);stmtupt.prepare("update T_ADID set w=:1,pheno=:2 where obtid=:3 and adidate=to_date(:4,'yyyy-mm-dd hh24:mi:ss')");stmtupt.bindin(1,m_stadid1.w,3);stmtupt.bindin(2,m_stadid1.pheno,8);stmtupt.bindin(3,m_stadid.obtid,5);stmtupt.bindin(4,m_stadid1.adidate,19);}if (stmtsel.execute() != 0){invalidcount++; m_logfile->Write("stmtsel.execute() failed.\n%s\n%s\n",stmtsel.m_sql,stmtsel.m_cda.message); return stmtsel.m_cda.rc;}  iccount=0;stmtsel.next();  if (c!=28){invalidcount++;}  // 必须是正确的数据才进行插入和查询if(c==28){ if (iccount>0) {// 执行更新的SQL语句,一定要判断返回值,0-成功,其它-失败。if (stmtupt.execute() != 0){invalidcount++; m_logfile->Write("stmtupt.execute() failed.\n%s\n%s\n",stmtupt.m_sql,stmtupt.m_cda.message);return stmtupt.m_cda.rc;}updatecount++;}else{// 执行插入的SQL语句,一定要判断返回值,0-成功,其它-失败。if (stmtins.execute() != 0){invalidcount++; m_logfile->Write("stmtins.execute() failed.\n%s\n%s\n",stmtins.m_sql,stmtins.m_cda.message);return stmtins.m_cda.rc;}insertcount++;}}return 0;
}

5.能见度数据:无分隔符

如下第一行为obtid(p5432),time(2018…) ,第二行为vtime,vseeing,max_vseeing…



//visibility.cpp
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _visibility();
connection conn;
void EXIT(int sig);
int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理分区预警信号发布日志,并保存到数据库的T_VISIBILITY表中。\n");printf("/oracle/htidc/shqx/bin/visibility 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/oracle/htidc/shqx/bin/visibility /oracle/data/shqx/sdata/visibility /oracle/log/shqx/visibility.log shqx/pwdidc@snorcl11g_128 10\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");//11111111111111111111111111111111111111111111111111111111111111111111while (true){logfile.Write("开始扫描目录。\n");    if (Dir.OpenDir(argv[1],"P5*.TXT",1000,true,true)==false){ //扫描数据文件存放的目录,只匹配"Z_*.DTB"logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}while (true){if (Dir.ReadDir()==false) break;  if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}logfile.Write("连接数据库成功。\n");}  logfile.Write("开始处理文件%s...",Dir.m_FileName);  // 处理数据文件if (_visibility()==false) {logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//1111111111111111111111111111111111111111111111111111111111
bool _visibility()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}CVISIBILITY VISIBILITY(&conn,&logfile);char strBuffer[301];while (true){memset(strBuffer,0,sizeof(strBuffer));    if (File.Fgets(strBuffer,300,true)==false) break; // 从文件中获取一行记录UpdateStr(strBuffer,"  "," ",true);  // 把内容中的两个空格替换成一个空格// logfile.Write("%s\n",strBuffer);    // 把用逗号分隔的记录拆分到结构体中if (VISIBILITY.SplitBuffer(strBuffer)==false) { logfile.Write("%s拆分失败\n",strBuffer); continue; }   long rc=VISIBILITY.InsertTable();  // 把vsignallog容器中的值更新到T_SIGNALDATA表中  if ( (rc>=3113) && (rc<=3115) ) return false;if (rc != 0) { logfile.Write("插入失败%s\n",strBuffer); continue; }}conn.commit();File.CloseAndRemove();logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",VISIBILITY.totalcount,VISIBILITY.insertcount,VISIBILITY.updatecount,VISIBILITY.invalidcount);return true;
}
//_shqx.h
#ifndef _SHQX_H
#define _SHQX_H
#include "_public.h"
#include "_ooci.h
struct st_visbility
{char obtid[6];char time[20];
};
struct st_visbility1
{char vtime[20];char vseeing[7];char max_vseeing[7];char max_vseetime[20];char min_vseeing[7];char min_vseetime[20];char vseeing10[7];char max_vseeing10[7];char max_vseetime10[20];char min_vseeing10[7];char min_vseetime10[20];char qcc[11];
};
class CVISIBILITY
{public:int totalcount,insertcount,updatecount,invalidcount;  // 记录总数据、插入数、更新数、无效记录数。int c;//个数struct st_visbility m_stvis;struct st_visbility1 m_stvis1;vector<struct st_typthon> vtypthon;   // 容器存放一个文件的全部记录CVISIBILITY(connection *conn,CLogFile *logfile);~CVISIBILITY();void initdata();  // 数据初始化connection *m_conn;CLogFile   *m_logfile;int iccount;sqlstatement stmtsel,stmtins,stmtupt;// 把记录拆分到vsignallog容器中。bool SplitBuffer(const char *strBuffer);// 把vsignallog容器中的值更新到T_SIGNALDATA表中。long InsertTable();
};
#endif
//_shqx.cpp
#include "_shqx.h"
CVISIBILITY::CVISIBILITY(connection *conn,CLogFile *logfile)
{initdata();m_conn=conn; m_logfile=logfile;
}
void CVISIBILITY::initdata()
{totalcount=insertcount=updatecount=invalidcount=0;m_conn=0; m_logfile=0;memset(&m_stvis,0,sizeof(struct st_visbility));memset(&m_stvis1,0,sizeof(struct st_visbility1));
}
CVISIBILITY::~CVISIBILITY()
{}
bool CVISIBILITY::SplitBuffer(const char *strBuffer)
{totalcount++;CCmdStr CmdStr;CmdStr.SplitToCmd(strBuffer," ",true);c = CmdStr.CmdCount();if(CmdStr.CmdCount()==3){memset(&m_stvis,0,sizeof(struct st_visbility));char strtemp[101];memset(strtemp,0,sizeof(strtemp));CmdStr.GetValue(0,strtemp); STRNCPY(m_stvis.obtid,5,strtemp,5);STRNCPY(m_stvis.time,19,strtemp+5,8);}if (CmdStr.CmdCount()==1){memset(&m_stvis1,0,sizeof(struct st_visbility1));char strtemp[101];memset(strtemp,0,sizeof(strtemp));CmdStr.GetValue(0,strtemp); STRNCPY(m_stvis1.vtime,4,strtemp,4);STRNCPY(m_stvis1.vseeing,6,strtemp+4,6);STRNCPY(m_stvis1.max_vseeing,6,strtemp+10,6);STRNCPY(m_stvis1.max_vseetime,4,strtemp+16,4);STRNCPY(m_stvis1.min_vseeing,6,strtemp+20,6);STRNCPY(m_stvis1.min_vseetime,4,strtemp+26,4);STRNCPY(m_stvis1.vseeing10,6,strtemp+30,6);STRNCPY(m_stvis1.max_vseeing10,6,strtemp+36,6);STRNCPY(m_stvis1.max_vseetime10,4,strtemp+42,6);STRNCPY(m_stvis1.min_vseeing10,6,strtemp+48,6);STRNCPY(m_stvis1.min_vseetime10,4,strtemp+54,4);STRNCPY(m_stvis1.qcc,10,strtemp+58,10);}return true;
}long CVISIBILITY::InsertTable()
{if (stmtsel.m_state==0){stmtsel.connect(m_conn);stmtsel.prepare("select count(*) from T_VISIBILITY where obtid=:1 and time=to_date(:2,'yyyymmdd') and vtime=:3");stmtsel.bindin(1,m_stvis.obtid,5);stmtsel.bindin(2,m_stvis.time,19);stmtsel.bindin(3,m_stvis1.vtime,19);stmtsel.bindout(1,&iccount);}if (stmtins.m_state==0){stmtins.connect(m_conn);stmtins.prepare("insert into T_VISIBILITY  values(:1,to_date(:2,'yyyymmdd'),:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,sysdate,SEQ_VISIBILITY.nextval)");stmtins.bindin( 1, m_stvis.obtid,5);stmtins.bindin( 2, m_stvis.time,19);stmtins.bindin( 3, m_stvis1.vtime,4);stmtins.bindin( 4, m_stvis1.vseeing,6);stmtins.bindin( 5, m_stvis1.max_vseeing,6);stmtins.bindin( 6, m_stvis1.max_vseetime,4);stmtins.bindin( 7, m_stvis1.min_vseeing,6);stmtins.bindin( 8, m_stvis1.min_vseetime,4);stmtins.bindin( 9, m_stvis1.vseeing10,6);stmtins.bindin( 10, m_stvis1.max_vseeing10,6);stmtins.bindin( 11, m_stvis1.max_vseetime10,4);stmtins.bindin( 12, m_stvis1.min_vseeing10,6);stmtins.bindin( 13, m_stvis1.min_vseetime10,4);stmtins.bindin( 14, m_stvis1.qcc,10);  }if (stmtupt.m_state==0){stmtupt.connect(m_conn);stmtupt.prepare("update T_VISIBILITY set obtid=:1,vtime=:2 where obtid=:1 and vtime=:2");stmtupt.bindin(1,m_stvis.obtid,5);stmtupt.bindin(2,m_stvis1.vtime,19);}if (stmtsel.execute() != 0){invalidcount++; m_logfile->Write("stmtsel.execute() failed.\n%s\n%s\n",stmtsel.m_sql,stmtsel.m_cda.message); return stmtsel.m_cda.rc;}  iccount=0;stmtsel.next();if (c!=1){invalidcount++;}if(c==1){if (iccount>0) {if (stmtupt.execute() != 0){invalidcount++; m_logfile->Write("stmtupt.execute() failed.\n%s\n%s\n",stmtupt.m_sql,stmtupt.m_cda.message);return stmtupt.m_cda.rc;}updatecount++;}else{if (stmtins.execute() != 0){invalidcount++; m_logfile->Write("stmtins.execute() failed.\n%s\n%s\n",stmtins.m_sql,stmtins.m_cda.message);return stmtins.m_cda.rc;}insertcount++;}}return 0;
}

6.计算:gunzip,imp

如下是区域自动站z/s文件原始数据入库后导出的文件。

如下expdat.dmp.gz解压后变为expdat.dmp。

fromuser是指expdat.dmp从哪个用户导出来的。

T_AREAOBTCODE表在下面数据计算生成其他数据集用不到,如下10天降雨量也多适合计算。

分钟数据表和原始数据结构和数据一样,其他业务系统用分钟数据表。


< tname >T_AREAOBTMIND</ tname >原始 , < train >T_GDOBTRAIND< /train > 雨量。T_GDAWSDAYD日,T_GDOBTREALD最新,T_GDOBTHOURD整点。如下select出后一定要排序,时间在前的一定先进去先算。

7.数据交换:数据导出为文件,数据文件推送


将导出后的数据进行数据推送,系统间数据交换采用ftp即公共协议比较多。

如下增量导出还要按keyid排序,每次导出数据时会把最大的keyid保存起来,导出的是xml文件。假如要导出1万条记录,每1000条分拆到一个xml文件中【for_hb(环保),%d:1,2…】。where后1=1是为了格式和下面保持一致好传参数< andstr >。如下xml中的ddatetime是to char(…)的别名,keyid>:1就是>(之前导过的keyid)。

// exptables.cpp
#include "_public.h"
#include "_ooci.h"
struct st_arg // 主程序的参数
{char connstr[101];char charset[51];char tname[51];char cols[1001];char fieldname[1001];char fieldlen[501];int  exptype;char andstr[501];char bname[51];char ename[51];char taskname[51];char exppath[301];int  timetvl;
} starg;
CLogFile logfile;
connection conn;
bool _exptables();  // 本程序的业务流程主函数
void EXIT(int sig);
vector<string> vfieldname; // 存放拆分fieldname后的容器
vector<int>    vfieldlen;  // 存放拆分fieldlen后的容器
int maxfieldlen;           // 存放fieldlen的最大值
void SplitFields();        // 拆分fieldname和fieldlen
void _help(char *argv[]); // 显示程序的帮助
long maxkeyid;   // 已导出数据的最大的keyid
bool LoadMaxKeyid(); // 从系统参数T_SYSARG表中加载已导出数据的最大的keyid
bool UptMaxKeyid();  // 更新系统参数T_SYSARG表中已导出数据的最大的keyid
bool _xmltoarg(char *strxmlbuffer); // 把xml解析到参数starg结构中int main(int argc,char *argv[])
{if (argc!=3) { _help(argv); return -1; }CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[1],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[1]); return -1;}  if (_xmltoarg(argv[2])==false) return -1; // 把xml解析到参数starg结构中while (true){ // 连接数据库 //放while (true)外面连耗资源    if (conn.connecttodb(starg.connstr,starg.charset) != 0){logfile.Write("connect database %s failed.\n",starg.connstr); sleep(starg.timetvl); continue;}// logfile.Write("export table %s.\n",starg.tname);if (_exptables() == false) logfile.Write("export tables failed.\n"); //导出数据的主函数conn.disconnect();   // 断开与数据库的连接sleep(starg.timetvl);}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//1111111111111111111111111111111111111111111111111111111111111111111111
void _help(char *argv[])
{printf("\n");printf("Using:/htidc/public/bin/exptables logfilename xmlbuffer\n\n");printf("增量导出示例:\n");printf("/htidc/public/bin/exptables /log/shqx/exptables_surfdata_for_hb.log \"<connstr>shqx/pwdidc@snorcl11g_198</connstr><charset>Simplified Chinese_China.ZHS16GBK</charset><tname>T_SURFDATA</tname><cols>obtid,to_char(ddatetime,'yyyymmddhh24miss'),t,p,u,wd,wf,r,vis</cols><fieldname>obtid,ddatetime,t,p,u,wd,wf,r,vis</fieldname><fieldlen>5,14,8,8,8,8,8,8,8</fieldlen><exptype>1</exptype><andstr> and obtid in ('59293','50745')</andstr><bname>SURFDATA_</bname><ename>_for_hb</ename><taskname>SURFDATA_FOR_HB</taskname><exppath>/data/shqx/exp/tohb</exppath><timetvl>30</timetvl>\"\n\n");printf("全量导出示例:\n");printf("/htidc/public/bin/exptables /log/shqx/exptables_obtcode_for_hb.log \"<connstr>shqx/pwdidc@snorcl11g_198</connstr><charset>Simplified Chinese_China.ZHS16GBK</charset><tname>T_OBTCODE</tname><cols>obtid,obtname,provname,lat,lon,height</cols><fieldname>obtid,obtname,provname,lat,lon,height</fieldname><fieldlen>5,30,30,8,8,8</fieldlen><exptype>2</exptype><andstr> and rsts=1 and obtid in ('59293','50745')</andstr><bname>OBTCODE_</bname><ename>_for_hb</ename><exppath>/data/shqx/exp/tohb</exppath><timetvl>300</timetvl>\"\n\n");printf("本程序是数据中心的公共功能模块,从数据库的表中导出数据生成xml文件,用于数据交换。\n");printf("logfilename是本程序运行的日志文件。\n");printf("xmlbuffer为文件传输的参数,如下:\n");printf("数据库的连接参数 <connstr>shqx/pwdidc@snorcl11g_198</connstr>\n");printf("数据库的字符集 <charset>Simplified Chinese_China.ZHS16GBK</charset> 这个参数要与数据源数据库保持>一致,否则会出现中文乱码的情况。\n");printf("待导出数据的表名 <tname>T_SURFDATA</tname>\n");printf("需要导出字段的列表 <cols>obtid,to_char(ddatetime,'yyyymmddhh24miss'),t,p,u,wd,wf,r,vis</cols> 可以采用函数。\n");printf("导出字段的别名列表 <fieldname>obtid,ddatetime,t,p,u,wd,wf,r,vis</fieldname> 必须与cols一一对应。\n");printf("导出字段的长度列表 <fieldlen>5,14,8,8,8,8,8,8,8</fieldlen> 必须与cols一一对应。\n");printf("导出数据的方式 <exptype>1</exptype> 1-增量导出;2-全量导出,如果是增量导出,要求表一定要有keyid字段。\n");printf("导出数据的附加条件 <andstr> and obtid in ('59293','50745')</andstr> 注意,关键字and不能少。\n");printf("导出文件的命名的前部分 <bname>SURFDATA_</bname>\n");printf("导出文件的命名的后部分 <ename>_for_hb</ename>\n");printf("导出任务的命名 <taskname>SURFDATA_FOR_HB</taskname> 当exptype=1时该参数有效。\n");printf("导出文件存放的目录 <exppath>/data/shqx/exp/tohb</exppath>\n");printf("导出数据的时间间隔 <timetvl>30</timetvl> 单位:秒,建议大于10。\n");printf("以上参数,除了taskname和andstr,其它字段都不允许为空。\n\n\n");
}bool _xmltoarg(char *strxmlbuffer)
{memset(&starg,0,sizeof(struct st_arg));GetXMLBuffer(strxmlbuffer,"connstr",starg.connstr);if (strlen(starg.connstr)==0) { logfile.Write("connstr is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"charset",starg.charset);if (strlen(starg.charset)==0) { logfile.Write("charset is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"tname",starg.tname);if (strlen(starg.tname)==0) { logfile.Write("tname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"cols",starg.cols);if (strlen(starg.cols)==0) { logfile.Write("cols is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"fieldname",starg.fieldname);if (strlen(starg.fieldname)==0) { logfile.Write("fieldname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"fieldlen",starg.fieldlen);if (strlen(starg.fieldlen)==0) { logfile.Write("fieldlen is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"exptype",&starg.exptype);if ( (starg.exptype!=1) && (starg.exptype!=2) ) { logfile.Write("exptype is not in (1,2).\n"); return false; }GetXMLBuffer(strxmlbuffer,"andstr",starg.andstr);if (strlen(starg.andstr)==0) { logfile.Write("andstr is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"bname",starg.bname);if (strlen(starg.bname)==0) { logfile.Write("bname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"ename",starg.ename);if (strlen(starg.ename)==0) { logfile.Write("ename is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"taskname",starg.taskname);if ( (starg.exptype==1) && (strlen(starg.taskname)==0) ) { logfile.Write("taskname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"exppath",starg.exppath);if (strlen(starg.exppath)==0) { logfile.Write("exppath is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"timetvl",&starg.timetvl);if (starg.timetvl==0) { logfile.Write("timetvl is null.\n"); return false; }// 拆分fieldname和fieldlenSplitFields();// 判断fieldname和fieldlen中元素的个数一定要相同if (vfieldname.size() != vfieldlen.size() ) { logfile.Write("fieldname和fieldlen的元素个数不同。.\n"); return false; }return true;
}//111111111111111111111111111111111111111本程序的业务流程主函数
bool _exptables()
{// 从系统参数T_SYSARG表中加载已导出数据的最大的keyidif (LoadMaxKeyid()==false) { logfile.Write("LoadMaxKeyid() failed.\n"); return false; } // 生成导出数据的SQL语句char strsql[4096]; char fieldvalue[vfieldname.size()][maxfieldlen+1]; // 输出变量定义为一个二维数组//第一维vfieldname.size()字段个数(限制fieldvalue外个数),第二维maxfieldlen+1字段长度(限制fieldvalue内个数),+1是最后一个空字符结尾符//导出数据的结果不管是字符串,整数还是浮点数都用字符串存放memset(strsql,0,sizeof(strsql));if (starg.exptype==1)  //增量导出, order by keyid排完序后数据好导入sprintf(strsql,"select %s,keyid from %s where 1=1 and keyid>%ld %s order by keyid",starg.cols,starg.tname,maxkeyid,starg.andstr);else //全量导出不需要keyidsprintf(strsql,"select %s from %s where 1=1 %s",starg.cols,starg.tname,starg.andstr);sqlstatement stmt(&conn);stmt.prepare(strsql);  for (int ii=0;ii<vfieldname.size();ii++){stmt.bindout(ii+1,fieldvalue[ii],vfieldlen[ii]); //绑定变量从1开始算}// 如果是增量导出,还要绑定keyid字段if (starg.exptype==1) stmt.bindout(vfieldname.size()+1,&maxkeyid);      if (stmt.execute() != 0)  // 执行导出数据的SQL{logfile.Write("select %s failed.\n%s\n%s\n",starg.tname,stmt.m_cda.message,stmt.m_sql); return false;}int  iFileSeq=1;   // 待生成文件的序号,临时变量,文件名不会重复了char strFileName[301],strLocalTime[21];CFile File;while (true){   // 如果在循环外面打开文件,stmt.next若是没记录又要删除文件memset(fieldvalue,0,sizeof(fieldvalue));   if (stmt.next() !=0) break;    if (File.IsOpened()==false)  // 把数据写入文件{memset(strLocalTime,0,sizeof(strLocalTime));LocalTime(strLocalTime,"yyyymmddhh24miss");memset(strFileName,0,sizeof(strFileName));sprintf(strFileName,"%s/%s%s%s_%d.xml",starg.exppath,starg.bname,strLocalTime,starg.ename,iFileSeq++);if (File.OpenForRename(strFileName,"w")==false){logfile.Write("File.OpenForRename(%s) failed.\n",strFileName); return false;}File.Fprintf("<data>\n");}for (int ii=0;ii<vfieldname.size();ii++){ //数据一个字段一个字段写入xml文件中File.Fprintf("<%s>%s</%s>",vfieldname[ii].c_str(),fieldvalue[ii],vfieldname[ii].c_str());}File.Fprintf("<endl/>\n");//111111111111111111111111111111111111111111111111111111111111if (stmt.m_cda.rpc%1000==0)  //每写入1000行关闭文件{File.Fprintf("</data>\n");if (File.CloseAndRename()==false){logfile.Write("File.CloseAndRename(%s) failed.\n",strFileName); return false;}// 更新系统参数T_SYSARG表中已导出数据的最大的keyidif (UptMaxKeyid()==false) { logfile.Write("UptMaxKeyid() failed.\n"); return false; }logfile.Write("create file %s ok.\n",strFileName);}}//1111111111111111111111111111111111111111111111111111111111if (File.IsOpened()==true) //不够1000条的写入一个文件{File.Fprintf("</data>\n");if (File.CloseAndRename()==false){logfile.Write("File.CloseAndRename(%s) failed.\n",strFileName); return false;}// 更新系统参数T_SYSARG表中已导出数据的最大的keyidif (UptMaxKeyid()==false) { logfile.Write("UptMaxKeyid() failed.\n"); return false; }logfile.Write("create file %s ok.\n",strFileName);}if (stmt.m_cda.rpc>0) logfile.Write("本次导出了%d条记录。\n",stmt.m_cda.rpc);return true;
}//1111111111111111111111111111111111111111111111111111
void SplitFields() //拆分fieldname和fieldlen
{vfieldname.clear(); vfieldlen.clear(); maxfieldlen=0;  CCmdStr CmdStr;CmdStr.SplitToCmd(starg.fieldname,",");vfieldname.swap(CmdStr.m_vCmdStr);int ifieldlen=0;CmdStr.SplitToCmd(starg.fieldlen,",");for (int ii=0;ii<CmdStr.CmdCount();ii++){  CmdStr.GetValue(ii,&ifieldlen); //maxfieldlen一开始为0if (ifieldlen>maxfieldlen) maxfieldlen=ifieldlen; //得到fieldlen的最大值maxfieldlenvfieldlen.push_back(ifieldlen);}
}//111111111111111111111111111111111从系统参数T_SYSARG表中加载已导出数据的最大的keyid
bool LoadMaxKeyid() //实现增量采集必须把每次导出数据的keyid保存起来,所以采用一个T_SYSARG参数表
{   //taskname作为参数代码argcodeif (starg.exptype!=1) return true; //只有增量导出才需要加载/更新系统参数表sqlstatement stmt(&conn);stmt.prepare("select argvalue from T_SYSARG where argcode=:1");stmt.bindin(1,starg.taskname,50);stmt.bindout(1,&maxkeyid);if (stmt.execute() != 0){logfile.Write("select T_SYSARG failed.\n%s\n%s\n",stmt.m_cda.message,stmt.m_sql); return false;}// 如果记录不存在,插入一新记录。if (stmt.next() != 0){ //一直只有一条记录:SURFDATA_FOR_HB,SURFDATA_FOR_HB,0stmt.prepare("insert into T_SYSARG(argcode,argname,argvalue) values(:1,:2,0)");stmt.bindin(1,starg.taskname,50);stmt.bindin(2,starg.taskname,50);stmt.execute();conn.commit();}// logfile.Write("maxkeyid=%d\n",maxkeyid);return true;
}//1111111111111111111111111111111111更新系统参数T_SYSARG表中已导出数据的最大的keyid
bool UptMaxKeyid() //导出前加载,导出后更新
{if (starg.exptype!=1) return true;sqlstatement stmt(&conn);stmt.prepare("update T_SYSARG set argvalue=:1 where argcode=:2");stmt.bindin(1,&maxkeyid);stmt.bindin(2,starg.taskname,50);if (stmt.execute() != 0){logfile.Write("select T_SYSARG failed.\n%s\n%s\n",stmt.m_cda.message,stmt.m_sql); return false;}conn.commit();return true;
}

下面为全量导出站点参数表。


vi …1.xml,只导出了2条记录一个文件。

下面为增量导出地面观测数据表。


//ftpputfiles.cpp系统间传输
#include "_public.h"
#include "_ftp.h"
struct st_arg
{char host[51];int  mode;char username[31];char password[31];char localpath[301];char remotepath[301];char matchname[301];int  ptype;char localpathbak[301];char okfilename[301];int  timetvl;
} starg;
Cftp ftp;
CLogFile logfile;
bool _ftpputfiles();
vector<struct st_fileinfo> vlistfile,vlistfile1;
vector<struct st_fileinfo> vokfilename,vokfilename1;
bool LoadListFile(); // 把localpath目录下的文件加载到vlistfile容器中
bool LoadOKFileName(); // 把okfilename文件内容加载到vokfilename容器中// 把vlistfile容器中的文件与vokfilename容器中文件对比,得到两个容器
// 一、在vlistfile中存在,并已经发送成功的文件vokfilename1
// 二、在vlistfile中存在,新文件或需要重新发送的文件vlistfile1
bool CompVector();
// 把vokfilename1容器中的内容先写入okfilename文件中,覆盖之前的旧okfilename文件
bool WriteToOKFileName();
// 如果ptype==1,把发送成功的文件记录追加到okfilename文件中
bool AppendToOKFileName(struct st_fileinfo *stfileinfo);
void EXIT(int sig);
void _help(char *argv[]);
bool _xmltoarg(char *strxmlbuffer);  //把xml解析到参数starg结构中int main(int argc,char *argv[])
{if (argc!=3) { _help(argv); return -1; }CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[1],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[1]); return -1;} if (_xmltoarg(argv[2])==false) return -1;  // 把xml解析到参数starg结构中while (true){if (ftp.login(starg.host,starg.username,starg.password,starg.mode)==false){logfile.Write("ftp.login(%s,%s,%s) failed.\n",starg.host,starg.username,starg.password); sleep(10); continue;}// logfile.Write("ftp.login ok.\n");  _ftpputfiles();ftp.logout();sleep(starg.timetvl);}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//111111111111111111111111111111111111111本程序的业务流程主函数
bool _ftpputfiles()
{// 创建远程服务器上的目录,不关心返回值。能成功就创建,没权限不能成功创建就算了ftp.mkdir(starg.remotepath);// 把localpath目录下的文件加载到vlistfile容器中if (LoadListFile()==false) {logfile.Write("LoadListFile() failed.\n"); return false;}if (starg.ptype==1){// 加载okfilename文件中的内容到容器vokfilename中LoadOKFileName();// 把vlistfile容器中的文件与vokfilename容器中文件对比,得到两个容器// 一、在vlistfile中存在,并已经发送成功的文件vokfilename1// 二、在vlistfile中存在,新文件或需要重新发送的文件vlistfile1CompVector();// 把vokfilename1容器中的内容先写入okfilename文件中,覆盖之前的旧okfilename文件WriteToOKFileName();    // 把vlistfile1容器中的内容复制到vlistfile容器中vlistfile.clear(); vlistfile.swap(vlistfile1);}//111111111111111111111111111111111把客户端的新文件或已改动过后的文件发送给服务端for (int ii=0;ii<vlistfile.size();ii++){char strremotefilename[301],strlocalfilename[301];SNPRINTF(strlocalfilename,300,"%s/%s",starg.localpath,vlistfile[ii].filename);SNPRINTF(strremotefilename,300,"%s/%s",starg.remotepath,vlistfile[ii].filename);logfile.Write("put %s ...",strlocalfilename);if (ftp.put(strlocalfilename,strremotefilename,true)==false)  // 发送文件{logfile.WriteEx("failed.\n"); break;}logfile.WriteEx("ok.\n");    if (starg.ptype==2) REMOVE(strlocalfilename);  // 删除文件    if (starg.ptype==3) // 转存到备份目录{char strfilenamebak[301];memset(strfilenamebak,0,sizeof(strfilenamebak));sprintf(strfilenamebak,"%s/%s",starg.localpathbak,vlistfile[ii].filename);if (RENAME(strlocalfilename,strfilenamebak)==false){logfile.Write("RENAME %s to %s failed.\n",strlocalfilename,strfilenamebak); return false;}}  // 如果ptype==1,把发送成功的文件记录追加到okfilename文件中if (starg.ptype==1) AppendToOKFileName(&vlistfile[ii]);} return true;
}//111111111111111111111111111111111把localpath目录下的文件加载到vlistfile容器中
bool LoadListFile()
{vlistfile.clear();CDir Dir;// 不包括子目录// 注意,如果目录下的总文件数超过50000,增量发送文件功能将有问题if (Dir.OpenDir(starg.localpath,starg.matchname,50000,false,false)==false){logfile.Write("Dir.OpenDir(%s) 失败。\n",starg.localpath); return false;}struct st_fileinfo stfileinfo;while (true){memset(&stfileinfo,0,sizeof(struct st_fileinfo));if (Dir.ReadDir()==false) break;strcpy(stfileinfo.filename,Dir.m_FileName);  // 文件名,不包括目录名strcpy(stfileinfo.mtime,Dir.m_ModifyTime);stfileinfo.filesize=Dir.m_FileSize;vlistfile.push_back(stfileinfo);// logfile.Write("vlistfile filename=%s,mtime=%s\n",stfileinfo.filename,stfileinfo.mtime);}return true;
}//111111111111111111111111111111111把okfilename文件内容加载到vokfilename容器中
bool LoadOKFileName()
{vokfilename.clear();CFile File;// 注意:如果程序是第一次发送,okfilename是不存在的,并不是错误,所以也返回true。if (File.Open(starg.okfilename,"r") == false) return true;struct st_fileinfo stfileinfo;char strbuffer[301];while (true){memset(&stfileinfo,0,sizeof(struct st_fileinfo));if (File.Fgets(strbuffer,300,true)==false) break;GetXMLBuffer(strbuffer,"filename",stfileinfo.filename,300);GetXMLBuffer(strbuffer,"mtime",stfileinfo.mtime,20);vokfilename.push_back(stfileinfo);// logfile.Write("vokfilename filename=%s,mtime=%s\n",stfileinfo.filename,stfileinfo.mtime);}return true;
}//11111111111111111111111111111把vlistfile容器中的文件与vokfilename容器中文件对比,得到两个容器
// 一、在vlistfile中存在,并已经发送成功的文件vokfilename1
// 二、在vlistfile中存在,新文件或需要重新发送的文件vlistfile1
bool CompVector()
{vokfilename1.clear();  vlistfile1.clear();for (int ii=0;ii<vlistfile.size();ii++){int jj=0;for (jj=0;jj<vokfilename.size();jj++){if ( (strcmp(vlistfile[ii].filename,vokfilename[jj].filename)==0) &&(strcmp(vlistfile[ii].mtime,vokfilename[jj].mtime)==0) ){vokfilename1.push_back(vlistfile[ii]); break;}}if (jj==vokfilename.size()){vlistfile1.push_back(vlistfile[ii]);}}/*for (int ii=0;ii<vokfilename1.size();ii++){logfile.Write("vokfilename1 filename=%s,mtime=%s\n",vokfilename1[ii].filename,vokfilename1[ii].mtime);}for (int ii=0;ii<vlistfile1.size();ii++){logfile.Write("vlistfile1 filename=%s,mtime=%s\n",vlistfile1[ii].filename,vlistfile1[ii].mtime);}*/return true;
}//111111111111111111把vokfilename1容器中的内容先写入okfilename文件中,覆盖之前的旧okfilename文件
bool WriteToOKFileName()
{CFile File;  if (File.Open(starg.okfilename,"w",false) == false) // 注意,打开文件不要采用缓冲机制{logfile.Write("File.Open(%s) failed.\n",starg.okfilename); return false;}for (int ii=0;ii<vokfilename1.size();ii++){File.Fprintf("<filename>%s</filename><mtime>%s</mtime>\n",vokfilename1[ii].filename,vokfilename1[ii].mtime);}return true;
}//1111111111111111111111111如果ptype==1,把发送成功的文件记录追加到okfilename文件中
bool AppendToOKFileName(struct st_fileinfo *stfileinfo)
{CFile File;if (File.Open(starg.okfilename,"a",false) == false){logfile.Write("File.Open(%s) failed.\n",starg.okfilename); return false;}File.Fprintf("<filename>%s</filename><mtime>%s</mtime>\n",stfileinfo->filename,stfileinfo->mtime);return true;
}//111111111111111111111111111111111显示程序的帮助
void _help(char *argv[])
{printf("\n");printf("Using:/htidc/public/bin/ftpputfiles logfilename xmlbuffer\n\n");printf("Sample:/htidc/public/bin/ftpputfiles /log/shqx/ftpputfiles_surfdata.log \"<host>172.16.0.15:21</host><port>21</port><mode>1</mode><username>oracle</username><password>te.st1234TES@T</password><localpath>/data/shqx/ftp/surfdata</localpath><remotepath>/data/shqx/sdata/surfdata</remotepath><matchname>SURF_*.TXT,*.DAT</matchname><ptype>1</ptype><localpathbak></localpathbak><okfilename>/data/shqx/ftplist/ftpputfiles_surfdata.xml</okfilename><timetvl>30</timetvl>\"\n\n\n");printf("本程序是数据中心的公共功能模块,用于把本地目录中的文件发送到远程的FTP服务器。\n");printf("logfilename是本程序运行的日志文件。\n");printf("xmlbuffer为文件传输的参数,如下:\n");printf("<host>118.89.50.198:21</host> 远程服务器的IP和端口。\n");printf("<mode>1</mode> 传输模式,1-被动模式,2-主动模式,缺省采用被模式。\n");printf("<username>wucz</username> 远程服务器FTP的用户名。\n");printf("<password>test1234TEST</password> 远程服务器FTP的密码。\n");printf("<localpath>/tmp/ftpput</localpath> 本地文件存放的目录。\n");printf("<remotepath>/tmp/gzrad</remotepath> 远程服务器存放文件的目录。\n");printf("<matchname>*.GIF</matchname> 待发送文件匹配的文件名,采用大写匹配,"\"不匹配的文件不会被发送,本字段尽可能设置精确,不允许用*匹配全部的文件。\n");printf("<ptype>1</ptype> 文件发送成功后,本地文件的处理方式:1-什么也不做;2-删除;3-备份,如果为3,还要指定备份的目录。\n");printf("<localpathbak>/tmp/gzradbak</localpathbak> 文件发送成功后,本地文件的备份目录,此参数只有当ptype=3时才有效。\n");printf("<okfilename>/oracle/qxidc/list/ftpgetfiles_surfdata.xml</okfilename> 已采集成功文件名清单,此参数只有当ptype=1时有效。\n");printf("<timetvl>30</timetvl> 发送时间间隔,单位:秒,建议大于10。\n\n");
}bool _xmltoarg(char *strxmlbuffer)
{memset(&starg,0,sizeof(struct st_arg));GetXMLBuffer(strxmlbuffer,"host",starg.host);if (strlen(starg.host)==0) { logfile.Write("host is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"mode",&starg.mode);if ( (starg.mode!=1) && (starg.mode!=2) ) starg.mode=1;GetXMLBuffer(strxmlbuffer,"username",starg.username);if (strlen(starg.username)==0) { logfile.Write("username is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"password",starg.password);if (strlen(starg.password)==0) { logfile.Write("password is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"localpath",starg.localpath);if (strlen(starg.localpath)==0) { logfile.Write("localpath is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"remotepath",starg.remotepath);if (strlen(starg.remotepath)==0) { logfile.Write("remotepath is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"matchname",starg.matchname);if (strlen(starg.matchname)==0) { logfile.Write("matchname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"ptype",&starg.ptype);if ( (starg.ptype!=1) && (starg.ptype!=2) && (starg.ptype!=3) ){ logfile.Write("ptype is error.\n"); return false; }GetXMLBuffer(strxmlbuffer,"localpathbak",starg.localpathbak);if ((starg.ptype==3) && (strlen(starg.localpathbak)==0)) { logfile.Write("localpathbak is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"okfilename",starg.okfilename);if ((starg.ptype==1) && (strlen(starg.okfilename)==0)) { logfile.Write("okfilename is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"timetvl",&starg.timetvl);if (starg.timetvl==0) { logfile.Write("timetvl is null.\n"); return false; }return true;
}

【C/C++12】天气APP:不同数据建表入表,数据交换(exptables.cpp,ftpputfiles.cpp)相关推荐

  1. 【C/C++13】天气APP:数据挖掘/HTTP协议/非结构化数据存储(filetoblob.cpp),数据管理/监控告警(hsmtable.cpp,tbspaceinfo.cpp)

    文章目录 1. 数据挖掘:/etc/rc.local,sudo su 2.HTTP协议:优先wget 3.非结构化数据存储:blob,pzhrain24file 4.数据管理子系统:数据字典表 5.监 ...

  2. 【C/C++11】天气APP:txt/xml文件处理入库(psurfdata.cpp,_shqx.h),数据结构设计(PowerDesigner)

    文章目录 1.txt/xml文件入表/自身调度:结构体内容 2.分区/表空间/网络/主键/错误优化:chown -R 用户 3.历史文件/表数据清理:生成测试数据后去采集,采集后未删除文件,因为数据不 ...

  3. GIS数据建库基本思想(下)

    作者:Flyingis 3.      数据规范 这里说的数据规范,指的是可以被系统所正确识别的数据.这依赖于上述数据库建库的第一个过程,即数据库标准的制定和数据规范.这里的主要矛盾在于,因为 GIS ...

  4. mysql大量数据分页优化_mysql大量数据分页优化

    一般我们数据量大的时候,然后就需要进行分页,一般分页语句就是limit offset,rows.这种分页数据量小的时候是没啥影响的,一旦数据量越来越大随着offset的变大,性能就会越来越差.下面我们 ...

  5. Android 天气APP(二十七)增加地图天气的逐小时天气、太阳和月亮数据

    上一篇:Android 天气APP(二十六)增加自动更新(检查版本.通知栏下载.自动安装) 效果图 开发流程 1.功能优化 2.地图天气中增加逐小时天气 3.地图天气中增加太阳和月亮数据 1.功能优化 ...

  6. Android 天气APP(五)天气预报、生活指数的数据请求与渲染

    上一篇:Android 天气APP(四)搭建MVP框架与使用 天气预报.生活指数的数据请求与渲染 新版------------------- 一.增加天气接口地址 二.增加API接口 三.天气数据存储 ...

  7. Android 天气APP(十)继续优化、下拉刷新页面天气数据

    上一篇:Android 天气APP(九)细节优化.必应每日一图 修复每日一图,增加下拉刷新,滑动改变标题 新版------------------- 一.修复每日请求必应壁纸Bug 二.增加下拉刷新 ...

  8. Android 天气APP(二十一)滑动改变UI、增加更多天气数据展示,最多未来15天天气预报

    上一篇:Android 天气APP(二十)增加欢迎页及白屏黑屏处理.展示世界国家/地区的城市数据 前言   写APP是有很多细节需要处理的,这些细节可以提高你的APP的使用概率.这已经是第二十一篇文章 ...

  9. 简易的安卓天气app(二)——适配器、每小时数据展示

    ✅简易的安卓天气app(一)--解析Json数据.数据类封装

最新文章

  1. iOS视频硬编码技术
  2. Python——with语句、context manager类型和contextlib库
  3. android studio wcf,将图像从android studio上传到Wcf Service
  4. 【ORACLE SQL 语言】SQL语言四大类
  5. 写一个算法统计在输入字符串中各个字符出现的频度
  6. 我都服了,为啥上游接口返回的汉字总是乱码?
  7. java的outputstream_Java OutputStream类
  8. 项目疑难杂症记录(四):Activity被重新创建的原因分析
  9. mac的java代码生成器为什么文件路径是这样的
  10. 图片右侧加文字html完整代码,怎么用css在图片右下方添加文字
  11. AJAX 聊天室实现原理终极解析
  12. 轻松在线绘制进化树和增加热图注释
  13. halcon学习之路
  14. 计算机文化基础形考作业,(精华版)国家开放大学电大专科《计算机文化基础》网络课形考任务6作业及答案(2页)-原创力文档...
  15. zcmu oj 1087: 统计字符
  16. 如何给word文档加水印
  17. C++课程设计-失物招领系统
  18. 高性能MySQL读书摘要(五)创建高性能的索引
  19. Redis配置不当致使root被提权漏洞
  20. 尼康相机测试软件mac版,尼康Webcam Utility

热门文章

  1. 【drp 12】再识转发和重定向:SpringMVC无法跳转页面
  2. EventSource
  3. 【转】MySQL的语句执行顺序
  4. NDK(三方库引入、Mk文件)
  5. M2第三天DailyScrum——PM(李忠)
  6. 单链表的快速排序(转)
  7. markdown mysql高亮_修改博客园markdown编辑器代码高亮风格的方法
  8. 批量打印pdf并合并_CAD批量打印攻略
  9. Java黑皮书课后题第8章:**8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行、整列或者对角线都是1或0的行、列和对角线
  10. com.esri.android,解决ArcGIS Android Could not find class 'com.esri.android.map.MapView'问题