【发布时间】:2013-12-28 00:20:25
【问题描述】:
编辑
存在解决方案 - 使用 std::ios::binary 而不是以文本模式打开文件(尽管文件是纯文本)解决了该问题。 tellg() 现在报告正确的位置,因此 seekg() 现在可以用于返回相同的位置。
结束编辑
不久前,我们遇到了服务器问题。主服务器很好,但辅助服务器有点小问题。我们想知道在此期间是否有任何不同的记录。
我们知道日志文件之间存在 other 差异这一事实 - 它们的长度不同,因为当一个或另一个较早时发生日志记录。因此,我们不能进行直线逐行比较——我们可能会得到数千行,这些行被报告为不同的记录,但只是被顶部附近的一台服务器额外记录的两行抵消,而没有被记录另一个。
我正在编写一个程序来根据时间戳比较输出文本文件;也就是说,转到发生打嗝的时间戳周围的区域,并仅针对该区域逐行比较。这就是tellg() 和 seekg() 出现问题的地方。
首先,这个循环对两个日志文件都运行:
while( getline(inputFile, inputLine) && loopBreak != 1 && inputFile.good() ){
if (firstOpen.empty()){
if ( -1 != inputLine.find("TimeOfFirstEntry") ){
firstOpen = inputLine;
}
}
if (!firstOpen.empty() && lastOpen.empty()){
if ( -1 != inputLine.find("TimeOfLastEntry") ){
lastOpen = inputLine;
}
}
if (!firstOpen.empty() && !lastOpen.empty()){
if ( -1 != inputLine.find(timeStamp) ){
if (0 == firstLineInBucket){
firstLineInBucket = inputFile.tellg();
lastLineInBucket = inputFile.tellg();
}
else{
lastLineInBucket = inputFile.tellg();
}
}
if ( (0 != firstLineInBucket) && (0 != lastLineInBucket) ){
if ( (-1 != inputLine.find("OccuranceTime") ) && (-1 == inputLine.find(timeStamp)) ){
loopBreak = 1;
}
}
}
}
稍后,这个循环进行比较:
if(inputPrimary.good() && inputSecondary.good() && output.good()){
inputPrimary.seekg(Primary.getFirstBucket());
inputSecondary.seekg(Secondary.getFirstBucket());
std::string linePrimary;
std::string lineSecondary;
while( getline(inputPrimary, linePrimary)
&& getline(inputSecondary, lineSecondary)
&& (inputPrimary.tellg() < Primary.getLastBucket())
&& (inputSecondary.tellg() < Secondary.getLastBucket()) ){
if(linePrimary == lineSecondary){
//Do nothing
}
else{
output << linePrimary << " .:|:. " << lineSecondary << "\n";
}
}
inputPrimary.close();
inputSecondary.close();
output.close();
}
这就是事情变得奇怪的地方:当我在一对文件上运行这个已知良好的时间戳(也就是说,它们都具有该时间戳的相同内容)时,内容被写入输出文件。进一步调查显示,在两个文件中报告写入的行不同,因为对于辅助服务器日志文件,seekg() 操作将位置放在行的开头,但对于主服务器日志文件,seekg () 操作将位置放置在距离最后一个换行符更远的位置 ~11 个字符。
到底是什么原因造成的?
【问题讨论】:
-
您使用什么类型来存储偏移量? 13 GB 将溢出 32 位类型。位置是完全错误的,还是真的只有 11 个字符?
-
当您使用它时,只需使用
std::istream::pos_type。它甚至不是一个裸整数。 -
1.包括相关的声明和数据类型。 2. 提及它应该如何工作的理论,而不仅仅是目标是什么(这也有点模糊)。 3. 简化为可重现的测试用例。 4. 添加cmets。问题很可能出现在您的代码中,因为回溯到文件中的某个点已经过很好的测试。