C/C++从文件开头按行读取内容==并无需新建文件,获取前部分内容
2016-03-02 10:23
627 查看
需求分析:
按行获取文件内容,达到行数要求或者其他要求(时间)后,停止读取,并将剩余内容删除。
文件格式:(按时间排序)
=========红色为所需内容,剩余内容删除=============
2016030115031110F9FDC6521100020000000000000000
2016030115021110F9FDC6521100020000000000000000
2016030115011110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030114001110F9FDC6521100020000000000000000
2016030114001110F9FDC6521100020000000000000000
2016030114201110F9FDC6521100020000000000000000
实现:
方法1:按行循环读取文件内容,并将符合要求的内容写入缓存,新建文件,将缓存写入新建文件中,删除旧文件,新文件重命名
优点:使用广泛
缺点:效率低,大数据时不适应
方法2:因为文件内容按规律(时间)有序排序,获取符合要求内容所在位置tellg(),使用chFileSize()函数修改文件大小,将不需要的内容删掉。
优点:效率较高
缺点:使用场景有局限性,待完善
方法1代码:
方法2代码:
按行获取文件内容,达到行数要求或者其他要求(时间)后,停止读取,并将剩余内容删除。
文件格式:(按时间排序)
=========红色为所需内容,剩余内容删除=============
2016030115031110F9FDC6521100020000000000000000
2016030115021110F9FDC6521100020000000000000000
2016030115011110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030115001110F9FDC6521100020000000000000000
2016030114001110F9FDC6521100020000000000000000
2016030114001110F9FDC6521100020000000000000000
2016030114201110F9FDC6521100020000000000000000
实现:
方法1:按行循环读取文件内容,并将符合要求的内容写入缓存,新建文件,将缓存写入新建文件中,删除旧文件,新文件重命名
优点:使用广泛
缺点:效率低,大数据时不适应
方法2:因为文件内容按规律(时间)有序排序,获取符合要求内容所在位置tellg(),使用chFileSize()函数修改文件大小,将不需要的内容删掉。
优点:效率较高
缺点:使用场景有局限性,待完善
方法1代码:
int nPushBack = 0;//符合要求的记录条数 vector<string>vecFileList;//缓存 int maxMinute = nMaxMinute;//需要查询的最大时间 int maxRec = nMaxRecord;//需要查询的最大记录条数 string strFileName = AFC_DATA_PATH + "trandata.filelist"; string strFileNamenew = AFC_DATA_PATH + "trandata.filelist.new"; int nLen = sizeofFile(strFileName.c_str());//文件大小 if (nLen <=0) return; fstream fs_tranfilelst(strFileName.c_str()); if (!fs_tranfilelst.good())//文件打开失败 return; CAfcStringTools afcStringTools; char bufLine[MAX_CHAR_IN_LINE], bufTemp[MAX_CHAR_IN_LINE]; //按行获取文件内容 while (fs_tranfilelst.getline(bufLine, MAX_CHAR_IN_LINE)) { if (afcStringTools.AfcConfTrimLine(bufLine, bufTemp, MAX_CHAR_IN_LINE, AfcConfCharNOChangeMode) == 0)//剔除空行 continue; // if is blank line, continue //time1 提取出YYYYMMDDHHMM201612201530 char chTimeBuf[16]; memset(chTimeBuf, 0, sizeof(chTimeBuf)); char* pTemp = bufTemp; memcpy(chTimeBuf, pTemp, 12); //time2 本地时间转换为妙数 - maxMinute*60 = 再转换为本地时间样式 char chTmpBuf[128]; memset(chTmpBuf, 0, sizeof(chTmpBuf)); time_t t_MaxTime; t_MaxTime = time(NULL);//获取当前时间的秒数 t_MaxTime = t_MaxTime - maxMinute * 60; tm *tm_MaxTime = localtime(&t_MaxTime);//将妙数转换为标准时间格式 strftime(chTmpBuf, 64, "%Y%m%d%H%M", tm_MaxTime);//标准时间格式20151220123025 //差异: //比较time1 和 time2 //时间要求满足并且记录条数未到 if ((memcmp(chTmpBuf, chTimeBuf, 12) <= 0) && (nPushBack <= maxRec)){ string strTmp = bufTemp; vecFileList.push_back(strTmp); continue; } fs_tranfilelst.close(); break; } fileExist(strFileName.c_str());//新建文件 fstream fs_tranfilelstnew(strFileName.c_str()); do{ if (vecFileList.size() <= 0) break; vector<string>::iterator iter = vecFileList.end() - 1; if (iter == vecFileList.end()) break; strName = *iter ; fs_tranfilelstnew.write(strName.c_str(),strName.length() ); vecFileList.erase(iter ); } while (true); fs_tranfilelstnew.close();
方法2代码:
int nPushBack = 0;//符合要求的记录条数 long longFileSize = 0;//文件大小 int maxMinute = nMaxMinute;//需要查询的最大时间 int maxRec = nMaxRecord;//需要查询的最大记录条数 string strFileName = AFC_DATA_PATH + "trandata.filelist"; int nLen = sizeofFile(strFileName.c_str());//文件大小 if (nLen <=0) return; fstream fs_tranfilelst(strFileName.c_str()); if (!fs_tranfilelst.good())//文件打开失败 return; CAfcStringTools afcStringTools; char bufLine[MAX_CHAR_IN_LINE], bufTemp[MAX_CHAR_IN_LINE]; //按行获取文件内容 while (fs_tranfilelst.getline(bufLine, MAX_CHAR_IN_LINE)) { if (afcStringTools.AfcConfTrimLine(bufLine, bufTemp, MAX_CHAR_IN_LINE, AfcConfCharNOChangeMode) == 0)//剔除空行 continue; // if is blank line, continue //time1 提取出YYYYMMDDHHMM201612201530 char chTimeBuf[16]; memset(chTimeBuf, 0, sizeof(chTimeBuf)); char* pTemp = bufTemp; memcpy(chTimeBuf, pTemp, 12); //time2 本地时间转换为妙数 - maxMinute*60 = 再转换为本地时间样式 char chTmpBuf[128]; memset(chTmpBuf, 0, sizeof(chTmpBuf)); time_t t_MaxTime; t_MaxTime = time(NULL);//获取当前时间的秒数 t_MaxTime = t_MaxTime - maxMinute * 60; tm *tm_MaxTime = localtime(&t_MaxTime);//将妙数转换为标准时间格式 strftime(chTmpBuf, 64, "%Y%m%d%H%M", tm_MaxTime);//标准时间格式20151220123020 //差异: //比较time1 和 time2 //时间要求满足并且记录条数未到 if ((memcmp(chTmpBuf, chTimeBuf, 12) <= 0) && (nPushBack <= maxRec)){ nPushBack++; longFileSize = (long)fs_tranfilelst.tellg();//获取到此位置文件数据大小 printf("nPushBack =%d ,need save the filelist = %s \n", nPushBack, bufTemp); continue; } fs_tranfilelst.close(); break; } //读写模式 int fd = open(strFileName.c_str(), O_RDWR); if (fd <= 0) return; //更改文件大小 chFileSize(fd, longFileSize); close(fd); 方法2使用到的函数:(基于POCO库) #include "Poco/File.h" #include "Poco/FileStream.h" #include "Poco/Exception.h" #include "Poco/BinaryReader.h" #include "Poco/BinaryWriter.h" #include "Poco/DirectoryIterator.h" /** * 改变文件大小 * 如果指定的长度小于文件长度, 则文件被截短; * 如果指定的长度大于文件长度, 则在文件后面补0; * 如果指定文件不存在, 则创建指定大小的文件(内容全为0) * pFilename - 文件名称(完整路径) * size - 需要改变的文件新的长度 * 返回值: 成功返回0,否则返回-1 */ int chFileSize( const char *pFileName, long size ) { int nFd; nFd = open( pFileName, O_RDWR | O_CREAT, 0666 ); if ( nFd >= 0 ) { int nReturn = chFileSize( nFd, size ); close( nFd ); return nReturn; } else return -1; } /** * 改变文件大小 * 如果指定的长度小于文件长度, 则文件被截短; * 如果指定的长度大于文件长度, 则在文件后面补0; * fd - 使用open打开的文件句柄 * size - 需要改变的文件新的长度 * 返回值: 成功返回0,否则返回-1 */ int chFileSize( const int fd, long size ) { #ifdef POCO_OS_FAMILY_WINDOWS return chsize( fd, size ); #else return ftruncate( fd, size ); #endif } bool fileExists(const char* pFileName, bool bAutoCreate) { try { Poco::File file( pFileName ); if ( !file.exists() && bAutoCreate ) { Poco::Path pathTmp( pFileName ); if ( pathTmp.isDirectory() ) file.createDirectories(); else if ( pathTmp.isFile() ) { File( basedir( string( pFileName ) ) ).createDirectories(); chFileSize( pFileName, 0 ); } } return ( file.exists() && file.canRead() ); } catch ( Poco::Exception& ex ) { logprintf("Warn: fileExists( %s ) %s\n", pFileName, ex.message().c_str() ); } catch ( ... ) { logprintf("Warn: fileExists( %s )\n", pFileName ); } return false; }
相关文章推荐
- 自主输入数值求和及平均值(数组的应用)
- [C/C++基础]读写文件
- Cpp--关于windows.h头文件
- 深入理解C++中public、protected及private用法
- C++语言-07-异常处理和信号处理
- c++命名空间
- c/c++将整数转换为字符串
- C语言——数组、函数、指针
- 关于C++中函数指针的使用
- c++时间函数
- C++中的explicit关键字
- C++中执行windows指令
- 编程语言之C++的学习
- C语言设置文本颜色和移动光标
- c语言数据类型 之 内存对齐与位段
- 2015年蓝桥杯省赛B组C/C++(试题+答案)前几题
- 2014第五届蓝桥杯C++B组第七题
- c语言:用函数找大数
- c语言面试题1
- 《Effective C++》学习笔记——条款39