【问题标题】:Quickly seek a location in a file快速查找文件中的位置
【发布时间】:2012-03-28 01:50:14
【问题描述】:

我有一个包含大量数字的文件,每个数字用空格分隔。

如:124 1212 5 654 74231 ...

如何快速找到该文件中的第 N 个数字?

我认为fseek() 可能不起作用,因为它是按字节衡量的,我可以通过以下方式获得第 N 个数字:

 int i;
 for (i=0;i!=N-1;++i) fscanf(somefile,"%d",&variable);

但我想可能有一些更有效的方法?

【问题讨论】:

  • 一旦您使用 fscanf 等在文件中找到了一个位置,您可以使用 ftell() 获取文件指针的字节位置,您可以将其传递给 fseek 以返回该位置位置几乎是即时的。
  • @MarcB 不幸的是,我不需要返回刚刚找到的号码。我可能会在找到数十万个其他号码后返回。
  • 除非文件中存储的数字具有某些属性(例如,它们都是 3 位长),否则唯一的方法是通读整个文件,直到达到第 N 个整数。
  • 或者索引该死的文件以供以后读取,也许? :q

标签: c++ c file scanf fseek


【解决方案1】:

读取整个文件一次并为文件中的一些数据点创建索引(例如 1000 个点)。 index 中的每个条目都可以将文件中的位置映射到从该位置开始的第 N 个数字。建立该索引后,每次查找第 N 个数字时,首先在索引中找到最近的条目,该条目告诉您文件中您可以fseek 到的最近的已知点。然后使用fscanf 执行搜索以找到该值。这减少了搜索时间,但代价是为索引使用了一些内存。

索引中的条目可能如下所示: (文件偏移量,编号N)

索引可能如下所示: (文件偏移量 1,编号 1) (文件偏移量 2,编号 2) ... (文件偏移量N,编号N)

【讨论】:

    【解决方案2】:

    如果您创建文件,那么另外两个选项是:

    1. 在一个足够宽的固定宽度字段中打印每个数字以容纳最大数字(例如“%5d”),然后将fseek(somefile,(N-1)*6,SEEK_SET) 定位到数字 N。

    2. 如果文件不需要人类可读,您可以 fwrite() 将整数作为二进制数据而不是 ASCII 字符写入文件并使用

      fseek(somefile,(N-1)*sizeof(int),SEEK_SET)
      fread(&variable,sizeof(int),1,somefile)
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多