pra*_*bhu 3 c performance fseek
我有一个代码中的情况,其中有一个巨大的函数,逐行解析记录,验证和写入另一个文件.
如果文件中存在错误,它会调用另一个拒绝记录的函数并写入拒绝原因.
由于程序中存在内存泄漏,它会与SIGSEGV崩溃.从崩溃的位置"重新启动"文件的一种解决方案是将最后处理的记录写入简单文件.
为此,需要将处理循环中的当前记录号写入文件.如何确保循环内的文件上的数据被覆盖?
使用fseek首先在循环中定位/回放会降低性能吗?
记录的数量可以很多,有时(高达500K).
谢谢.
编辑:内存泄漏已得到修复.建议将重启解决方案作为额外的安全措施,并提供重启机制以及SKIP n记录解决方案.很抱歉没有提到它.
遇到这种问题时,您可以采用以下两种方法之一:
ftell输入文件上返回的位置)写出到单独的书签文件中.为了确保你从中断的地方恢复,不要引入重复的记录,你必须fflush在每次写入之后(对两者bookmark和输出/拒绝文件).这种和无缓冲的写操作一般会减慢典型(无故障) )场景显着.为了完整起见,请注意您有三种写入书签文件的方法:
fopen(..., 'w') / fwrite / fclose - 非常慢rewind / truncate / fwrite / fflush - 略快一点rewind / fwrite / fflush- 有点快 ; 您可以跳过,truncate因为记录号(或ftell位置)将始终与前一个记录号(或ftell位置)一样长或长,并且将完全覆盖它,前提是您在启动时截断文件一次(这将回答您的原始问题)fflush文件,或者至少不需要这样.fflush在切换到写入fflush拒绝文件之前,仍然需要主输出文件,然后在切换回写入主输出文件之前拒绝文件(对于500k记录输入可能需要几百或几千次.)只需删除从输出/拒绝文件的最后一个未终止的行,到该行的所有内容将是一致的.我强烈推荐方法#2.与方法#2所需的任何附加(缓冲)读取相比,方法#1所引入的写入(三种可能中的任何一种)都非常昂贵(fflush可能需要几毫秒;乘以500k并得到分钟 - 而计算数量500k记录文件中的行只需几秒钟,而且文件系统缓存正在使用,而不是针对您.)
编辑 只是想澄清实现方法2所需的确切步骤:
当写入输出并分别拒绝文件时,只需要在从写入文件切换到写入另一个文件时进行刷新.请考虑以下场景,说明执行这些文件刷新切换的必要性:
如果您对运行时的自动刷新之间的间隔不满意,您也可以每100个或每1000个记录手动刷新一次.这取决于处理记录是否比刷新更昂贵(如果处理更昂贵,经常刷新,可能在每个记录之后,否则只有在输出/拒绝之间切换时才会刷新.)
从失败中恢复
records_resume_counter)直到你到达文件末尾ftell),让我们称之为last_valid_record_ends_here\n或`r`)来轻松验证
fseek返回last_valid_record_ends_here并停止从此输出/拒绝文件中读取; 不要增加柜台; 继续下一个输出或拒绝文件,除非你已经完成了所有这些records_resume_counter从中跳过记录
last_valid_record_ends_here)的部分信息- 您将没有重复,垃圾或丢失记录.