我是C ++的新手,可能有一个愚蠢的问题。我有一个ifstream,我想把它分成两半左右。
有问题的文件是已排序的csv,我希望搜索文件每行的第一个值。
最终文件会非常大,所以我试图避免阅读文件的每一行。
e.g。
如果文件包含7行,我想拆分ifstream,得到包含前3行的1个流和包含最后4行的1个流。
答案 0 :(得分:1)
首先,使用this question的答案来确定文件的大小。然后将该数字除以2。逐行读取输入,并将其写入第一个输出流;每次通话后检查file.tellg()
。一旦超过中间点,将输出切换到第二个文件。
这不会在文件之间平均分割字符串,但这些字符串中的字符总数应该足够接近,并且不会将文件拆分到字符串中间
答案 1 :(得分:0)
将其视为具有一个巨大表的关系数据库。为了查找某个数据,您可以对整个表执行顺序扫描,也可以使用索引(必须可用于您要执行的查询类型)。
文本文件的典型索引是文件内的偏移列表,按索引表达式排序。如果csv文件已经按特定列排序,那么索引中的偏移量将是升序的,这有助于了解构建索引的时间。
所以基本上你必须先阅读一次文件,找出行结束的地方;这是排序列的索引。要查找特定元素,请使用binary search,使用索引查找数据集中的各个元素。
根据数据类型,您可以扩展索引以便在不读取实际数据表的情况下进行快速比较。例如,在单词列表中,您可以将单词的前四个字母保留在偏移旁边,这样您就可以快速进入正确的区域,并且只需要对最后一次访问进行数据读取(然后您可以将其优化为顺序扫描,因为文件系统可以更好地处理它。)
同样的技术也可以应用于其他列;当然,存储在索引中的偏移量不再按文件顺序升序。
由于它是CSV数据,因此也适用特殊情况:如果您拥有的唯一索引与文件数据本身的顺序相同,则可以轻松确定记录结束(即,您有固定记录长度,或者有一个明确的记录分隔符,例如EOL字符),然后可以省略构建实际索引并且猜测值(对于固定长度记录,偏移量总是等于索引中记录长度乘以偏移量;对于分离记录你可以跳到记录的中间并寻找下一个终结符;请注意,这里有二进制搜索的恶意极端情况)。但这确实意味着您将始终在此处读取数据页面,这比仅读取索引效率低。