问题与fstream :: tellg()和:: seekg()

时间:2013-12-10 12:57:09

标签: c++ fstream seek

修改

存在一个解决方案 - 用std :: ios :: binary而不是文本模式打开文件(尽管文件是纯文本)解决了这个问题。 tellg()现在报告正确的位置,因此现在可以使用seekg()返回到同一个地方。

结束编辑

前段时间,我们遇到了服务器问题。主服务器很好,但次要服务器有轻微的打嗝。我们想知道在那段时间内是否有任何不同的记录。

我们知道日志文件之间存在其他差异的事实 - 它们的长度不同,因为当一个或另一个先前已经关闭时会发生日志记录。因此,我们不能进行直线逐行比较 - 我们可能会得到数千条线路报告以不同的方式记录,但只是被顶部附近的一台服务器额外记录的两条线路偏移而未被记录另一个。

我正在编写一个程序,根据时间戳比较输出文本文件;也就是说,转到打嗝发生的时间戳周围区域,并逐行比较该区域。这就是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个字符。

究竟是什么导致这种情况?

2 个答案:

答案 0 :(得分:2)

任何好的diff程序都会向您显示不同的块。然后,您可以将结果加载到图形比较程序中,直观地扫描结果,忽略您知道的块不同,然后在遇到您不期望的块时尖叫。

例如, WinMerge

http://www.majorgeeks.com/index.php?ct=files&action=file&id=1668

答案 1 :(得分:0)

  

(是的,相对寻求不适用于以文本模式打开的文件)    - Cubbi

所以有答案 - 在std :: ios :: binary模式下打开可以解决问题。