读书人

C++文件操作解决方法

发布时间: 2013-10-14 12:54:46 作者: rapoo

C++文件操作
在一个日志文件中,如何使用C/C++标准库读取一个范围内的记录?

比如:读取在2012-08-10 01:10:23至2012-08-10 01:15:55之间的记录

....................
2012-08-10 01:10:23 200 9.26.107.207
2012-08-10 01:10:55 220 9.26.89.201
2012-08-10 01:12:15 120 9.26.107.112
2012-08-10 01:15:55 120 9.26.87.16
....................

如何利用lseek()读取两个时间点间的所有记录? 如果文件很大如何加速查找? 谢谢!
[解决办法]
参考下面的代码:


#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(int argc, char** argv)
{
ifstream fis("E:/access.txt");

if(!fis)
{
cout << "Can not open file" << endl;
exit(1);
}

string line;
while(fis.good())
{
getline(fis, line);

if(line.substr(0, 19) >= "2012-08-10 01:10:23" && line.substr(0, 19) <= "2012-08-10 01:15:55")
{
cout << line << endl;
}
}

fis.close();

return 0;
}


如果access.txt的内容是:

2012-08-10 01:10:20 200 10.26.107.207
2012-08-10 01:10:21 200 11.26.107.207
2012-08-10 01:10:22 200 12.26.107.207
2012-08-10 01:10:23 200 13.26.107.207
2012-08-10 01:10:55 200 14.26.107.207
2012-08-10 01:12:15 200 15.26.107.207
2012-08-10 01:15:55 200 16.26.107.207
2012-08-10 01:16:55 200 17.26.107.207
2012-08-10 01:16:56 200 18.26.107.207

那么将输出:

2012-08-10 01:10:23 200 13.26.107.207
2012-08-10 01:10:55 200 14.26.107.207
2012-08-10 01:12:15 200 15.26.107.207
2012-08-10 01:15:55 200 16.26.107.207

[解决办法]
不同的文件格式有不同的解析方法,下面的例子展示如何逐行读取并拆分,后续你再加上你的时间判别即可:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <string.h>

using namespace std;

#define LINE_LENGTH81

int main(int argc, char* argv[])
{
ifstream fin("log.txt");
char str[LINE_LENGTH];
vector<string> words;
while(fin.getline(str, LINE_LENGTH))
{
for(int i = 0, j = 0; i < strlen(str); ++i)
{
if(str[i] == ' ')
{
string temp(str + j, i - j);
words.push_back(temp);
cout << temp << endl;
j = i + 1;


}
}
}

return 0;
}


[解决办法]
思路大体如下:
如果文件长度不超过500000字节,全部读入内存。
否则读取文件前10行,统计平均每行的字节长度比如为L
用fseek(文件大于2GB时用_lseeki64)定位文件读指针(结合之前估算出的L值),采用二分搜索的思路快速定位起止时间在文件中的对应字节偏移量。

读书人网 >C++

热点推荐