快速访问ifs()C++; 信息:在TXT文件中存储位置、关闭文件、然后在C++中使用相同的位置打开文件的最佳方式是什么?

快速访问ifs()C++; 信息:在TXT文件中存储位置、关闭文件、然后在C++中使用相同的位置打开文件的最佳方式是什么?,c++,parsing,ifstream,seekg,C++,Parsing,Ifstream,Seekg,我有一个大的文本文件,我需要分块解析并输入到某个系统中。现在,我将文件加载到ifstream中,然后获取行,直到找到所需的数据(假设数据位于{x}位置)。在此之后,我关闭文件,处理数据,现在我需要继续从大文件中输入数据。所以我再次打开文件,获取行,直到这次到达位置{x+d}(d是我读取的数据的偏移量) 不需要一次浏览文件,很容易看到,我在文件中浏览了(1d+2d++…+(N-1)d+Nd)~d*N^2次。现在我想在d之后保存文件中的位置,关闭文件,然后立即在相同位置打开文件。什么可以用来做这个

我有一个大的文本文件,我需要分块解析并输入到某个系统中。现在,我将文件加载到ifstream中,然后获取行,直到找到所需的数据(假设数据位于{x}位置)。在此之后,我关闭文件,处理数据,现在我需要继续从大文件中输入数据。所以我再次打开文件,获取行,直到这次到达位置{x+d}(d是我读取的数据的偏移量)


不需要一次浏览文件,很容易看到,我在文件中浏览了(1d+2d++…+(N-1)d+Nd)~d*N^2次。现在我想在d之后保存文件中的位置,关闭文件,然后立即在相同位置打开文件。什么可以用来做这个

如果启用换行翻译(标准称之为“文本模式”),则无法执行此操作,因为返回位置需要标准库扫描文件的整个前端,以查找N个字符,而不是重复计算换行符。可变长度编码的翻译(例如UTF-8和UCS之间)会导致类似的问题


解决方案是关闭换行翻译(标准称之为“二进制模式”)和任何其他涉及可变长度编码的翻译,并自行处理。关闭所有翻译后,“文件位置”是操作系统直接用于执行文件I/O的数字,因此可能非常有效(是否有效取决于标准库的实现细节)。

启用换行翻译后无法执行此操作(标准称之为“文本模式”)),因为查找回该位置需要标准库扫描文件的整个正面,以查找N个字符,而不是重复计算换行符。可变长度编码的翻译(例如UTF-8和UCS之间)会导致类似的问题


解决方案是关闭换行翻译(标准称之为“二进制模式”)和任何其他涉及可变长度编码的翻译,并自行处理。关闭所有翻译后,“文件位置”是操作系统直接用于执行文件I/O的数字,因此有可能非常有效(它是否真正有效取决于标准库实现细节)。

您将使用相同的方法将位置存储在一个非常小的文件中。文件的大小没有任何实质性的区别。@SamVarshavchik:这不完全正确。对于大文件(特别是超过2GB的文件),您需要更加小心使用存储位置的数据类型。看起来您有标签?。。。这是C.@Sadikov——首先,这个文件有固定的行长吗?如果是这样,您不需要
getline
,因为您可以简单地使用偏移量来计算文件中的哪一行/哪一列。您可以使用与在非常小的文件中存储位置相同的方法。文件的大小没有任何实质性的区别。@SamVarshavchik:这不完全正确。对于大文件(特别是超过2GB的文件),您需要更加小心使用存储位置的数据类型。看起来您有标签?。。。这是C.@Sadikov——首先,这个文件有固定的行长吗?如果是这样,您不需要
getline
,因为您可以简单地使用偏移量来计算文件中的哪一行/哪一列。@Sadikov:如果您关闭换行转换,没有任何东西可以阻止您调用
getline()
,但是根据生成文件的软件,行的结尾可能是\r\n、\r或\n,而不仅仅是\r\n,这将影响getline的参数。操作系统用于执行文件I/O的数字是标准库传递给操作系统文件I/O函数的文件位置,例如,在窗口上,该窗口将是重叠的
结构的
Offset
OffsetHigh
成员。当翻译被关闭时,
tell
seek
使用的逻辑位置与操作系统的位置相同。@Sadikov:这是预期的,尽管可能有一个脑死亡库,它不实现“立即跳转”路径,只从一开始计算翻译是打开还是关闭。只需测量多长时间
seekg(大数)
+一个小的固定长度读取时间,您就可以轻松测试自己是否走上了快车道。您是否有此声明的参考资料?我的印象是,如果您使用tell返回的位置调用seek,您将精确地恢复文件位置(除非您的多字节编码是上下文编码),而不考虑翻译。@Ben:我真的不相信这种情况,这就是为什么我希望看到引用而不是您的断言。对于文本文件,您只能将KG查找到以前由SekPOS或SekOf返回的位置,这将是一个适合将文件位置重置为原来值的值,而不必调用Schlemiel的服务。C++最终推迟到C库,因此值得引用7.21.9节。C标准的第2部分,描述了ftell的返回值:“对于文本流,其文件位置指示器包含未指定的信息,可由
fseek
函数使用,用于将流的文件位置指示器返回到调用
ftell
时的位置;两个这样的返回值之间的差异不一定是对写入或读取字符数的有意义的度量。”@Sadikov:如果关闭换行转换,没有任何东西可以阻止您调用
getline()
,但根据生成文件的软件,行结尾可能是\r\n,