代码之家  ›  专栏  ›  技术社区  ›  pajton

fseek()如何在文件系统中实现?

  •  17
  • pajton  · 技术社区  · 15 年前

    这不是一个纯粹的编程问题,但是它会影响使用fseek()的程序的性能,因此了解它是如何工作的非常重要。一个小小的免责声明,这样它就不会关闭。

    我想知道在文件中间插入数据有多有效。假设我有一个包含1MB数据的文件,然后在512KB偏移处插入一些内容。与在文件末尾追加数据相比,效率如何?为了使示例完整,假设我要插入16KB的数据。

    我知道答案因文件系统的不同而不同,但是我假设在公共文件系统中使用的技术非常相似,我只想得到正确的概念。

    6 回复  |  直到 7 年前
        1
  •  5
  •   Giuseppe Guerrini    7 年前

    (免责声明:我只想在这个有趣的讨论中添加一些提示) 我有一些事情要考虑:

    1)fseek不是主系统服务,而是库函数。为了评估其性能,我们必须考虑如何实现文件流库。一般来说,文件i/o库在用户空间中添加了一层缓冲区,因此如果目标位置在当前缓冲区的内部或外部,fseek的性能可能会有很大的不同。而且,i/o库使用的系统服务可能会有很大的变化。也就是说,在某些系统上,库尽可能广泛地使用文件内存映射。

    2)正如您所说,不同的文件系统可能以非常不同的方式运行。特别是,我希望事务性文件系统必须做一些非常聪明的事情,而且可能代价高昂,以便准备在文件中间回滚已中止的写操作。

    3)现代操作系统有非常激进的缓存算法。一个“fseeked”文件可能已经存在于缓存中,因此操作变得更快。但如果其他进程产生的整个文件系统活动变得重要,它们可能会降低很多。

    有什么意见吗?

        2
  •  4
  •   Parjánya PinkyNoBrain    7 年前

    让我们以ext2 fs和linux操作系统为例。我认为insert和append之间不会有显著的性能差异。在这两种情况下,都必须读取文件节点和偏移表,将相关的磁盘扇区映射到内存中,更新数据,并在稍后将数据写入磁盘。在本例中,当访问文件的一部分时,会有很大的性能差异的是良好的时间和空间位置,因为这将减少加载/存储组合的数量。

    正如前面的回答所说,如果处理的数据是fs块大小的确切倍数,那么您可以加快这两个操作,在这种情况下,您可以跳过加载阶段,只需将新块插入到datastructure中的文件中。这是不实际的,因为您需要对fs驱动程序的低级别访问,使用它将是非常限制性的,并且不可移植。

        3
  •  3
  •   t0mm13b    15 年前

    fseek(...) 是库调用,而不是操作系统调用。运行时库负责处理对操作系统进行系统调用所涉及的实际开销,从技术上讲,fseek是间接地对系统进行调用,但实际上并非如此(这使库调用和系统ca之间的差异有了明显的区别ll)。 费雪(…) 是一个标准的输入输出函数,与底层系统无关…但是…这是一个很大的 然而

    操作系统很可能已经将文件缓存在其内核内存中,也就是说,直接偏移到磁盘上存储1和0的位置,它是通过操作系统的内核层的,很可能是内核中最顶层的一层,它将拥有文件是由数据组成的,也就是说,与它所包含的内容无关的数据(无论哪种方式,只要指向磁盘结构的指向磁盘上的lcoation的偏移量的指针是有效的!)…

    什么时候? fseek(..) 发生时,会有很多从头开始,间接地,内核委派从磁盘读取的任务,这取决于文件的碎片程度,理论上可能是“到处都是”,这可能是一个重要的从头开始,从用户地的角度来看,即EC代码执行 费雪(…) ,它可能将自己分散到各个地方,以将数据收集到“数据的一个连续视图”中,此后,插入文件的中间(记住在这个阶段,内核必须调整数据在实际磁盘盘中的位置/偏移量)将被认为是d比追加到文件末尾慢。

    原因很简单,内核“知道”最后一个偏移量是什么,只需擦除eof标记并插入更多数据,在幕后,内核就必须为磁盘缓冲区分配另一块内存,并在eof ma之后将调整后的偏移量分配到磁盘上的位置。Rker,一旦数据追加完成。

        4
  •  2
  •   Patrick Schlüter    14 年前

    我有一个观察 fseek 在solaris上,对它的每次调用都会重置 FILE . 下一次读取将始终读取一个完整的块(默认为8K)。所以如果你有大量的随机访问和少量的读取,最好在没有缓冲的情况下进行。( setvbuf 具有 NULL 缓冲区)甚至使用直接系统调用( lseek + read 或者更好 pread 它只是1个系统调用,而不是2)。我想其他操作系统也会有类似的行为。

        5
  •  1
  •   Ha.    15 年前

    只有当数据大小是fs扇区的倍数时,才可以有效地将数据插入文件的中间,但是os不提供这样的功能,因此必须使用fs驱动程序的低级接口。

        6
  •  1
  •   goedson    15 年前

    在文件中间插入数据比在文件末尾追加数据效率低,因为在插入时,必须在插入点之后移动数据,以便为要插入的数据腾出空间。移动这些数据需要从磁盘读取它们,写入要插入的数据,然后在插入的数据之后写入旧数据。所以在插入时至少有一个额外的读写操作。