fstream::tellg() 和 ::seekg() 的问题
Posted
技术标签:
【中文标题】fstream::tellg() 和 ::seekg() 的问题【英文标题】:Issue with fstream::tellg() and ::seekg() 【发布时间】: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。问题很可能出现在您的代码中,因为回溯到文件中的某个点已经过很好的测试。
【参考方案1】:
任何好的diff
程序都会向您展示不同的块。然后,您可以将结果加载到图形比较程序中,直观地扫描结果,忽略您知道不同的块,然后当你碰到意想不到的块时尖叫。
例如,WinMerge:
(来源:majorgeeks.com)
【讨论】:
@medivh:这听起来不像是保存日志文件的实用方法。 @medivh 这是什么,healthcare.gov?无论如何,只要您不尝试将所有内容都保存在内存中,现在 13 GB 是一个非常易于处理的文件大小。你肯定找不到没有的差异程序。 "我的字面意思是'字面意思'" @medivh:它应该被分割成更小的文件。很明显。 @medivh:FDA 是否批准了您的seekg()
/tellg()
代码不起作用?【参考方案2】:
(是的,相对搜索不适用于以文本模式打开的文件) -Cubbi
所以答案就出来了 - 在 std::ios::binary 模式下打开可以很好地解决问题。
【讨论】:
但是发布的代码没有使用相对搜索。如果有,那将是主要嫌疑人。以上是关于fstream::tellg() 和 ::seekg() 的问题的主要内容,如果未能解决你的问题,请参考以下文章
python 文件操作seek() 和 telll() 自我解释