文件合并程序
来源:互联网 发布:徐州网络推广学校 编辑:程序博客网 时间:2024/06/04 00:43
文件合并程序
程序的功能
将一个目录中的指定的文件进行合并或者拆分。
处理规则是:将指定目录中的指定的文件形成一个文件列表,对该列表中的每一个文件进行读取,一条一条地将记录写入目的文件,当目的文件达到指定的数量的时候,关闭旧的目的文件,打开新的目的文件,继续处理原始的记录。最终的后果就是,如果原始文件的记录较少,该程序实现了文件合并,如果原始文件的记录数量较多,该程序实现了文件的拆分。
使用到的系统函数有:
获取文件目录中文件列表的办法;
取得当前程序进程号;
获取时间的办法;
C++中读写文件的办法;
测试命令
程序的功能
将一个目录中的指定的文件进行合并或者拆分。
处理规则是:将指定目录中的指定的文件形成一个文件列表,对该列表中的每一个文件进行读取,一条一条地将记录写入目的文件,当目的文件达到指定的数量的时候,关闭旧的目的文件,打开新的目的文件,继续处理原始的记录。最终的后果就是,如果原始文件的记录较少,该程序实现了文件合并,如果原始文件的记录数量较多,该程序实现了文件的拆分。
使用到的系统函数有:
获取文件目录中文件列表的办法;
取得当前程序进程号;
获取时间的办法;
C++中读写文件的办法;
一些宏的使用;
#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <dirent.h>#include <string.h>#include <time.h>#include <vector>#include <string>#include <fstream>using namespace std;/*编译方法AIX:xlC_r -g -w -q64 -qwarn64 -brtl -bhalt:5 -o mergeCdr mergeCdr.cpp发布的时候,去掉“-g”*//*版本号定义规则1 主版本号,用于较大的程序改动0 次版本号,用于较小的需求改动0 每次的修改的bug 更改次数1 总的发布次数第一次版本的发布信息为: Ver 1.0.0.1*//*版本修改历史:Ver 1.0.0.1 功能点:支持程序将指定目录中的指定的文件,复制并备份到指定的目录Ver 1.1.0.2 功能点:支持将目的文件设定最大行数*/#define __VER__ "Ver 1.1.0.2"const int FILE_NAME_LEN = 256;//文件名的最大长度const int BUFFER_LEN = 4096;//清单中的一条记录的最大长度vector<string> vec_file;//用于存放需要处理的文件名称int nFileRows = 0;//合并后的文件的当前记录数量int nMaxFileRows = 0;//合并后的文件的最大记录数量char chFileMask[50] = { 0 };//命令行参数中传进来的输出文件名称的前缀int GetFile(char * src_dir, char *src_file_name);void usage(char *process_name);int DealOneFile(char *srcFileNameWithPath, char*bakFileNameWithPath,char * destFilePath, char * destFileName);int GetMMHHSS(char * mmhhss);int GetYYYYMMDD(char * yymmdd);int GetMMDD(char * mmdd);/*程序的参数:process_name sleep_time src_dir src_file_mask src_bak_dir dest_dir desc_file_mask file_rowsprocess_name 程序名字本身sleep_time 程序休眠的时间src_dir 原来的目录路径src_file_mask 原始文件的掩码src_bak_dir 备份文件的路径dest_dir 新的目录路径desc_file_mask 新的文件名称掩码file_rows 合并后的文件达到file_rows的记录后,重新建立一个文件启动方式举例:./mergeCdr 60 /hnibm/henan/mergeCdr A /hnibm/henan/mergeCdr/bak /hnibm/henan/mergeCdr A 3*/int main(int argc, char ** argv){printf("==============process [%s] begin...==============\n", argv[0]); //参数校验if(argc == 2 &&( strcmp(argv[1],"-v") == 0 || strcmp(argv[1],"-V") == 0 )){printf("current version is [%s]\nbulid time is [%s %s]\n",__VER__, __DATE__,__TIME__); return 0;}else if( argc != 8){printf("process need 7 parameters!\n");usage(argv[0]);return 2;}sprintf(chFileMask, "%s", argv[6]);nMaxFileRows = atol(argv[7]); //主要业务的处理while(true){//取得当前的日期和时间,用于生成目标文件名称 char szyyyymmdd[15] = {0}; GetYYYYMMDD(szyyyymmdd); char szhhmiss[15] = {0}; GetMMHHSS(szhhmiss); char szmmdd[10] = {0}; GetMMDD(szmmdd); printf("current date and time is [%s %s]!\n",szyyyymmdd,szhhmiss); //取得需要处理的文件列表 int ret = GetFile(argv[2],argv[3]); if(ret != 0) { return ret; } if(vec_file.size() == 0) { printf("no files to be need\n"); } else { printf("there are [%d] files need to deal\n",vec_file.size()); //规整输入的文件名称 char szSrcFilePath[FILE_NAME_LEN] = {0}; if(argv[2][strlen(argv[2])-1] != '/') { sprintf(szSrcFilePath,"%s%s",argv[2],"/"); } printf("src file path is [%s]\n",szSrcFilePath); //规整备份文件的路径名称 char szBakFilePath[FILE_NAME_LEN] = {0}; if(argv[4][strlen(argv[4])-1] != '/') { sprintf(szBakFilePath,"%s%s",argv[4],"/" ); } printf("backup file path is [%s]\n",szBakFilePath); //规整输出的路径名称char szDestFilePath[FILE_NAME_LEN] = { 0 }; if(argv[5][strlen(argv[5])-1] != '/') { sprintf(szDestFilePath,"%s%s",argv[5],"/" ); }char szDestFileNameTemp[FILE_NAME_LEN / 2] = { 0 };sprintf(szDestFileNameTemp, "%s_0%s%s_%s.r.XswapX", chFileMask, szmmdd, szhhmiss, szyyyymmdd); char szSrcFileNameWithPath[FILE_NAME_LEN] = {0}; char szBakFileNameWithPath[FILE_NAME_LEN] = {0}; for(vector<string>::iterator itr = vec_file.begin(); itr != vec_file.end(); itr ++) { memset(szSrcFileNameWithPath,0x00,FILE_NAME_LEN); memset(szBakFileNameWithPath,0x00,FILE_NAME_LEN); sprintf(szSrcFileNameWithPath,"%s%s",szSrcFilePath,itr->c_str()); sprintf(szBakFileNameWithPath,"%s%s",szBakFilePath,itr->c_str()); printf("begin to deal file [%s]\n",szSrcFileNameWithPath); //处理一个文件//特别需要注意参数 szDescFileNameTemp,当一个合并文件写满时,它的变量值在处理过程中会发生改变。ret = DealOneFile(szSrcFileNameWithPath, szBakFileNameWithPath, szDestFilePath, szDestFileNameTemp); if(ret) { //return ret; continue; } } //将目标文件的名称进行调整 char szCmd[1024] = {0};string strDestFileNameTemp(szDestFileNameTemp);sprintf(szCmd, "mv %s%s %s%s ", szDestFilePath, szDestFileNameTemp, szDestFilePath, strDestFileNameTemp.substr(0, strDestFileNameTemp.rfind(".")).c_str()); printf("final dest file: [%s]\n", szCmd); system(szCmd); } printf("==============sleep(%d)==============\n", atoi(argv[1])); sleep(atoi(argv[1]));}return 0;}void usage(char *process_name){printf("USAGE:\n");printf("\t[%s -v]\n",process_name);printf("\t[%s -V]\n",process_name);printf("\t[%s sleep_time src_dir src_file_name_mask src_bak_dir dest_dir dest_file_name_mask file_rows]\n",process_name);}int GetFile(char * src_dir, char *src_file_name){ printf("begin to get files in dir [%s], file name like [%s]\n", src_dir, src_file_name ); DIR *dp; struct dirent *dirp; if ((dp = opendir(src_dir)) == NULL) { printf("can't open [%s]\n", src_dir); return 3; } vec_file.clear(); int iSrcFileNameLen = strlen(src_file_name); while ((dirp = readdir(dp)) != NULL) { if(strcmp(dirp->d_name,".") == 0 || (strcmp(dirp->d_name,"..") == 0)) { continue; } if(strncmp(dirp->d_name,src_file_name,iSrcFileNameLen) != 0) { printf("file name is [%s], skip!\n", dirp->d_name); continue; }int nFileNameLen = strlen(dirp->d_name);if (! (dirp->d_name[nFileNameLen - 2] == '.' && dirp->d_name[nFileNameLen - 1] == 'r') ){printf("file name is [%s], skip!\n", dirp->d_name);continue;} vec_file.push_back(dirp->d_name); } closedir(dp); return 0;}int DealOneFile(char *srcFileNameWithPath, char*bakFileNameWithPath, char * destFilePath, char * destFileName){ ifstream src_file(srcFileNameWithPath);char szDestFileNameWithPath[FILE_NAME_LEN] = { 0 };sprintf(szDestFileNameWithPath, "%s%s", destFilePath, destFileName);printf("dest file name with path is [%s]\n", szDestFileNameWithPath);ofstream dest_file(szDestFileNameWithPath, ofstream::app); if(!src_file.is_open()) { printf("open src file [%s] Error\n",srcFileNameWithPath); return 4; } if(!dest_file.is_open()) {printf("open dest file [%s] Error\n", szDestFileNameWithPath); return 5; } char szBuffer[BUFFER_LEN] = {0}; //复制文件 while (! src_file.eof() ) { memset(szBuffer,0x00,BUFFER_LEN); /*//read 函数是读取一块数据,会有多行,不能使用此函数 src_file.read(szBuffer,BUFFER_LEN); dest_file << szBuffer; */ src_file.getline(szBuffer,BUFFER_LEN); if(strlen(szBuffer) == 0) { printf("empty line, skip\n" ); continue; } dest_file << szBuffer <<endl; nFileRows ++; //如果一个文件“被写满”,写下一个文件 if( nFileRows == nMaxFileRows) { printf("file is full, use next file\n"); nFileRows = 0;dest_file.close();//将目标文件的名称进行调整string strDestFileName(destFileName);char szCmd[1024] = { 0 };sprintf(szCmd, "mv %s %s%s", szDestFileNameWithPath, destFilePath, strDestFileName.substr(0, strDestFileName.rfind(".")).c_str());printf("final dest file: [%s]\n", szCmd);system(szCmd);//为了防止新的目标文件名与上一次产生的文件名重复sleep(1);char szyyyymmdd[15] = { 0 };GetYYYYMMDD(szyyyymmdd);char szhhmiss[15] = { 0 };GetMMHHSS(szhhmiss);char szmmdd[10] = { 0 };GetMMDD(szmmdd);//此处需要修改函数的入参,好让此文件名供后续的其他需要处理的源文件使用。sprintf(destFileName, "%s_0%s%s_%s.r.XswapX", chFileMask, szmmdd, szhhmiss, szyyyymmdd);sprintf(szDestFileNameWithPath, "%s%s", destFilePath, destFileName);printf("new dest file name with path is [%s]\n", szDestFileNameWithPath);dest_file.open(szDestFileNameWithPath, ofstream::app); } } //dest_file<<endl; dest_file.close(); src_file.close(); //将原始文件进行备份 char szCmd[1024] = {0}; sprintf(szCmd,"mv %s %s",srcFileNameWithPath,bakFileNameWithPath ); printf("backup file: [%s]\n", szCmd); system(szCmd); return 0;}int GetMMHHSS(char * mmhhss){ time_t current_time = time(0); struct tm *mStLocalTime = localtime(¤t_time); sprintf(mmhhss,"%02d%02d%02d",mStLocalTime->tm_hour,mStLocalTime->tm_min,mStLocalTime->tm_sec); return 0;}int GetYYYYMMDD(char * yymmdd){ time_t current_time = time(0); struct tm *mStLocalTime = localtime(¤t_time); sprintf(yymmdd,"%04d%02d%02d",mStLocalTime->tm_year+1900,mStLocalTime->tm_mon + 1,mStLocalTime->tm_mday); return 0;}int GetMMDD(char * mmdd){ time_t current_time = time(0); struct tm *mStLocalTime = localtime(¤t_time); sprintf(mmdd,"%02d%02d",mStLocalTime->tm_mon + 1,mStLocalTime->tm_mday); return 0;}
测试命令
测试命令:./mergeCdr 60 /hnibm/henan/mergeCdr A /hnibm/henan/mergeCdr/bak /hnibm/henan/mergeCdr A 1000
命令说明
./mergeCdr 程序本身的名称;
60 程序循环变量指定的原始文件目录时,所休眠的时间,以秒为单位;
/hnibm/henan/mergeCdr 程序需要处理的原始文件目录;
A 程序需要处理的原始文件目录中的以字符'A' 开头的文件名称;
/hnibm/henan/mergeCdr/bak 程序需要处理的原始文件在处理后的备份的路径;
/hnibm/henan/mergeCdr 程序需要存放的合并后的文件的路径;
A 合并后的文件的名称前缀,最终的文件名为“A_0mmddhhmiss_yyyymmdd.r”;
1000 合并后的文件的记录数量的最大值,当文件的记录数量达到此值后,系统会创建一个新的记录文件;
备注:
我测试的时候,原始文件的路径和合并后的文件存放的路径是一致的,原始文件的名称匹配字符和合并后的文件的名称前缀也是一致的,这种源和目的都一样的情况,会导致数据文件在下一个循环中进行重复处理,虽然不会导致话单错误,但是也是多此一举。所以,在实际生产中,不建议用这种方式进行配置。
阅读全文
0 0
- 文件合并c程序
- 文件合并程序
- 文件分割与合并程序
- python 合并文件小程序
- java 两个文件合并程序
- 【C++练习】文件合并程序
- C#写的文件切割合并程序
- 文件切割合并程序学习笔记
- JAVA写的文件分割与文件合并程序
- JAVA写的文件分割与文件合并程序
- JAVA写的文件分割与文件合并程序
- 合并烧写程序BIN文件的两种方法
- 合并烧写程序BIN文件的两种方法
- 文件合并
- 合并文件
- 文件合并
- 文件合并
- 文件合并
- [Leetcode] 220. Contains Duplicate III 解题报告
- Centos7部署Tensorflow Serving
- linux 下shell中if的“-e,-d,-f”是什么意思
- 云计算技巧在通信运营商的应用解析
- GeneratedKeyHolder的作用:获得新建主键值
- 文件合并程序
- python安装第三方的包
- C++三种(private,protected,public)继承方式的可见性说明
- 什么是CDN及CDN加速原理
- Cas4.2.7完整版部署文档
- MySQL基本概念
- 书籍-微服务架构与实践
- Android---adb的常见命令操作
- 查看医学影像文件软件