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

如何在内存中表示随机访问文本文件(C),c,file,memory,data-structures,C,File,Memory,Data Structures,我正在做一个项目,在这个项目中,我需要读取内存中的文本(源)文件,并能够对执行随机访问(例如,检索第3行第15列对应的地址) 我想知道是否有一个既定的方法来做到这一点,或数据结构,特别是对这项工作好。我需要能够执行(可能是摊销)恒定时间访问。我在C语言中工作,但如果值得的话,我愿意实现更高级别的数据结构 我的第一个想法是使用一个大缓冲区的链表,它将保存文件的字符数据。我还将创建一个数组,其索引是行号,内容是与行首相对应的地址。此阵列将根据需要重新分配 附属问题:有人知道源文件的平均大小吗?我很惊

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

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

我的第一个想法是使用一个大缓冲区的链表,它将保存文件的字符数据。我还将创建一个数组,其索引是行号,内容是与行首相对应的地址。此阵列将根据需要重新分配

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

澄清:

我关心的文件是源文件,所以它们的大小应该是可管理的,不应该修改它们,并且行具有变量长度(最大值)

我正在研究的问题主要需要一个只读文件表示,但我对挖掘这个问题非常感兴趣

结论:

本文对用于维护文件(支持读取/插入/删除)的数据结构进行了非常有趣的讨论

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

  • 解决方案:如果行的大小大致相同,则通过在每行添加所需数量的元字符,使所有行的长度相等。然后,您可以简单地从行号计算fseek()位置,使您的搜索为O(1)
  • 如果对行进行排序,则可以执行二进制搜索,使搜索为O(log(nõline))
  • 如果两者都不存在,则可以存储行行距的索引。但是,如果对文件进行了大量修改,就会出现问题,因为如果在某个位置插入X个字符,则必须计算它是哪一行,然后将该X添加到所有下一行。与删除类似。你基本上得到了O(nõ线)。代码变得丑陋
  • 如果要将整个文件存储在内存中,只需创建一行*char[]。然后,通过第一次解引用得到行,通过第二次解引用得到字符

  • 解决方案:如果行的大小大致相同,则通过在每行添加所需数量的元字符,使所有行的长度相等。然后,您可以简单地从行号计算fseek()位置,使您的搜索为O(1)
  • 如果对行进行排序,则可以执行二进制搜索,使搜索为O(log(nõline))
  • 如果两者都不存在,则可以存储行行距的索引。但是,如果对文件进行了大量修改,就会出现问题,因为如果在某个位置插入X个字符,则必须计算它是哪一行,然后将该X添加到所有下一行。与删除类似。你基本上得到了O(nõ线)。代码变得丑陋

  • 如果要将整个文件存储在内存中,只需创建一行*char[]。然后一行一行地取消引用,一个字符一个字符地取消引用。

    我不太确定这里的问题是什么,但似乎有点“如何将文件保存在内存中”和“如何对其进行索引”。由于您需要随机访问文件的内容,因此最好将文件映射到内存中,除非您的地址空间很紧


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

    我不太确定这里的问题是什么,但似乎存在“如何将文件保留在内存中”和“如何为其编制索引”这两个问题。由于您需要随机访问文件的内容,因此最好将文件映射到内存中,除非您的地址空间很紧

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

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

    2) 在第二个过程中,创建一个指针或偏移数组,这些指针或偏移指向该内存中的行首(提示:“\n”后面的一个)

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

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

    2) 在第二个过程中,创建一个指针或偏移数组,这些指针或偏移指向该内存中的行首(提示:“\n”后面的一个)


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

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

    当然,除非你的文件大小超过100KB左右,否则你就有问题了