首先需要了解ifstream 的 seekg函数,它主要是用于设置在输入流中的位置
file.seekg(0, ios::end);
ios::beg 从文件头开始计算偏移量
ios::end 从文件末尾开始计算偏移量
ios::cur 从当前位置开始计算偏移量
file.tellg();
用于在输入流中获取位置
其实本质上文件读写就是一个指针指向文件中某个位置后进行读写,所以简单来说tellg()和seekg()都是用于设置该指针的位置的。
主要函数如下,函数主要功能为调转到文件的最后一行,并解析最后一行的内容
void stringSplit(string str, char split,vector<string>& res) {
istringstream streamString(str);
string token;
while (getline(streamString, token, split))
{
//将token存入res
res.push_back(token);
}
}int getMaxTag(string fileName) {
//打开文件流,文件名为:fileName
ifstream file(fileName);
//如果无法打开此文件,return
if (!file.is_open()) {
ALOGD("getMaxTag: Can not open file!");
return -1;
}
//将指针移动到最后一行
file.seekg(0, ios::end);
//获取文件大小
std::streampos fileSize = file.tellg();
//如果文件大小<=0,则说明该文件没有内容,或者有问题
if (fileSize <= 0) {
ALOGD("File is empty.");
return 0;
}
char ch;
std::string lastLine;
long sizeOfFile = (long)fileSize-2;
while (sizesss >= 0) {
file.seekg(sizeOfFile);
file.get(ch);
//向前寻找\n, 找到\n则代表换行了,也就是倒数第二行的末尾
if (ch == '\n') {
std::getline(file, lastLine);
break;
}
--sizeOfFile;
}
ALOGD("file last line = %s", lastLine.c_str());
file.close();
if (lastLine == "") {
return 0;
}
long index = 0;
//format as bellow:
//{ tag1:3, tag2:1}
//格式加入是上面这种
vector<string> splitLastLine;
//以:分割字符串,分割后的分别存到splitLastLine,会被分割成“tag1", "3, tag2", "1"
stringSplit(lastLine, ':', splitLastLine);
vector<string> splitLastLineTag;
//以,分割字符串splitLastLine[1]
stringSplit(splitLastLine[1], ',', splitLastLineTag);
string indexMax = splitLastLineTag[0];
char* endptr;
//将string转成long
long num = strtol(indexMax.c_str(), &endptr, 10);
if (*endptr != '\0') {
ALOGD("getMaxTag: Change failed!");
return -1;
} else {
index = num;
}
ALOGD("max index = %ld", index);
return index;
}
请注意,以上代码当文件只有一行内容时会报错,因为是往前循环\n,而只有一行时是没有\n的,所以会crash, 以下是修正后的代码
void stringSplit(string str, char split,vector<string>& res) {
istringstream streamString(str);
string token;
while (getline(streamString, token, split))
{
//将token存入res
res.push_back(token);
}
}int getMaxTag(string fileName) {
//打开文件流,文件名为:fileName
ifstream file(fileName);
//如果无法打开此文件,return
if (!file.is_open()) {
ALOGD("getMaxTag: Can not open file!");
return -1;
}int lineCount = 0;
std::string lastLine;
while (std::getline(file, lastLine)) {
lineCount++;
if (lineCount > 1) {
break;
}
}
ALOGD("getContentIndex: lineCount = %d", lineCount);
if (lineCount == 1) {return1;
}
//将指针移动到最后一行
file.seekg(0, ios::end);
//获取文件大小
std::streampos fileSize = file.tellg();
//如果文件大小<=0,则说明该文件没有内容,或者有问题
if (fileSize <= 0) {
ALOGD("File is empty.");
return 0;
}
char ch;
long sizeOfFile = (long)fileSize-2;
while (sizesss >= 0) {
file.seekg(sizeOfFile);
file.get(ch);
//向前寻找\n, 找到\n则代表换行了,也就是倒数第二行的末尾
if (ch == '\n') {
std::getline(file, lastLine);
break;
}
--sizeOfFile;
}
ALOGD("file last line = %s", lastLine.c_str());
file.close();
if (lastLine == "") {
return 0;
}
long index = 0;
//format as bellow:
//{ tag1:3, tag2:1}
//格式加入是上面这种
vector<string> splitLastLine;
//以:分割字符串,分割后的分别存到splitLastLine,会被分割成“tag1", "3, tag2", "1"
stringSplit(lastLine, ':', splitLastLine);
vector<string> splitLastLineTag;
//以,分割字符串splitLastLine[1]
stringSplit(splitLastLine[1], ',', splitLastLineTag);
string indexMax = splitLastLineTag[0];
char* endptr;
//将string转成long
long num = strtol(indexMax.c_str(), &endptr, 10);
if (*endptr != '\0') {
ALOGD("getMaxTag: Change failed!");
return -1;
} else {
index = num;
}
ALOGD("max index = %ld", index);
return index;
}