如何在内存中表示随机访问文本文件(C)

时间:2011-09-02 10:08:08

标签: c file memory data-structures

我正在开发一个项目,我需要在内存中读取文本(源)文件并能够执行随机访问(例如,检索对应于第3行第15列的地址)。

我想知道是否有一种既定的方法可以做到这一点,或者数据结构是否特别适合这项工作。我需要能够执行(可能是摊销的)恒定时间访问。我在C工作,但如果值得的话,我愿意实现更高级别的数据结构。

我的第一个想法是使用一个大缓冲区的链表来保存文件的字符数据。我也会创建一个数组,其索引是行号,内容是对应行的开头的地址。这个数组将根据需要重新分配。

附属问题:有没有人知道源文件的平均大小?我很惊讶没有在谷歌上找到这个。

澄清:

我关注的文件是源文件,因此它们的大小应该是可管理的,它们不应该被修改,并且行具有变量长度(强制希望限制在某个最大值)。

我正在处理的问题主要是只读文件表示,但我对挖掘问题非常感兴趣。

Conlusion:

文章Data Structures for Text Sequences中有一个非常有趣的讨论用于维护文件的数据结构(具有读/插入/删除支持)。

如果你只需要只读,只需获取文件大小,用fread()在内存中读取它,然后你必须维护一个动态数组,它将行号(索引)映射到指向第一个字符的指针。线。下面的人建议懒惰地构建这个数组,这在许多情况下似乎是一个好主意。

6 个答案:

答案 0 :(得分:2)

我不太清楚这里的问题是什么,但似乎有一些“如何将文件保存在内存中”和“我如何将其编入索引”。由于您需要随机访问文件的内容,因此建议您对文件进行内存映射,除非您对地址空间不严格。

我认为你不能避免线性传递文件一次以找到行结尾。正如您所说,您可以创建指向每行开头的指针的索引。如果你不确定你需要多少索引,那就懒得创建它(按需)。如果在后续运行中需要它,您还可以将此索引存储到磁盘(作为偏移,而不是指针)。您可以根据文件大小和预期的行长度来估计索引的大小。

答案 1 :(得分:1)

  1. 解决方案:如果行大小相同,则通过向每行附加所需数量的元字符来使所有行等长。然后你可以简单地从行号计算fseek()位置,使你的搜索成为O(1)。
  2. 如果行已排序,那么您可以执行二进制搜索,使您的搜索成为O(log(nõLines))。
  3. 如果不存在,则可以存储行开头的索引。但是,如果你修改了很多文件,你会遇到问题,因为如果你在某处插入让我们说X字符,你必须计算它是哪一行,然后将这个X添加到所有下一行。与删除相似。 Yu基本上得到O(nõLines)。代码变得丑陋
  4. 如果要将整个文件存储在内存中,只需创建行* char []。然后,您可以通过第一个取消引用获得第一个引用并通过第二个引用来获得字符。

答案 2 :(得分:1)

1)将整个文件读取(或映射)到一块内存中。

2)在第二遍中创建一个指针或偏移量数组,指向行的开头(提示:'\ n'之后的一个)到该内存中。

现在,您可以索引数组以访问特定行。

答案 3 :(得分:1)

不可能同时在特定的行/列/字符地址插入,删除和读取O(1)。您可以获得的最佳结果是所有这些操作的同步O(log n),并且可以使用各种平衡二叉树将文件存储在内存中。

当然,除非您的文件大于100 kB左右,否则最好不要打扰任何花哨的东西,只使用平面线性缓冲区...

答案 4 :(得分:0)

答案 5 :(得分:0)

源文件的平均大小?这样的事情存在吗?源文件可以从0个字节到数千个字节,就像任何文本文件一样,它取决于它包含的字符数