11

典型的文件系统和 POSIX 接口只允许在最后调整文件大小。通常,关闭后“磁盘上”文件的大小等于关闭时读/写位置的偏移量。关闭前查找也称为“重新定位文件末尾”。

包含数据队列的文件可以通过删除文件开头的操作更有效地表示。可以释放开始时的磁盘分配块,并最大限度地减少不必要的复制。

这是否受到任何常见文件系统格式和/或操作系统的直接支持?使用什么样的接口来做到这一点?(例如,Linuxfcntl选择器。)我很确定我在实践中听说过这种东西。

4

4 回答 4

4

不。无论如何,在 Unix 世界中不是。

如果您查看 DBMS 或 Unix(ish) 文件系统内部结构,它们可以轻松地在开头、结尾或中间的任何位置截断或扩展数据集。但他们不导出该功能。它不是 Unix API 遗产或 POSIX 标准的一部分,因此任何“开头截断”或“开头扩展”的 API 都是非标准的(“专有”)。

这些功能的边际效用也不清楚。谁会使用它们?多常?

Unix 文件(字节/字符的平面序列)已经证明它们对应用程序代码简单有效,但对于分层数据结构的基础很差。25 年前,这一说法值得商榷。今天,这只是一个观察到的历史现实。

Unix 开发人员曾经争辩说“所有事物都可以简化为文件”和“我们可以通过巧妙的搜索来实现随机访问”。然而,这些说法从未完全奏效。例如,Unix 从未与小型机和大型机操作系统(例如 DEC RMS、IBM ISAM 和 VSAM)的随机访问记录管理能力相提并论。虽然那些实现文件系统、队列、尝试、关系数据库和对象存储的人偶尔会将内容放入文件中,并且他们将文件用于日志记录等顺序操作,但他们很少将字符流作为其低级格式。相反,他们使用 B 树和哈希表等结构来直接管理磁盘块、内存段和其他底层资源。

字符流属于表、文档和对象——适用于客户端应用程序的抽象。如果您想要一个队列,请考虑使用已经涵盖此内容的现有中间件(例如 RabbitMQ、ZeroMQ、REDIS、一些 DBMS 管理器)。如果您必须自己构建它,您可能不会在简单的字符流抽象之上构建它。因此,虽然在开始时截断/扩展可能对某些事情有用(例如,日志修剪而不是分段日志轮换),但对于大多数数据结构实现来说,它不太可能成为大赢家。

于 2013-08-08T12:56:27.630 回答
1

我见过的最接近的是文件格式,表明数据已被“删除”,然后删除的空间可以重新使用。这通常只适用于固定长度的记录格式,例如 DBF,并且需要更多的内存来维护已删除记录的索引以供重用以及文件中记录的顺序。

于 2013-08-07T09:10:04.783 回答
1

重新定位文件的开头可能不是一个好主意。这可能会混淆在该文件上打开文件描述符并期望它可以正确查找的进程,即具有可预测的偏移量。

如果您的主要目标只是节省磁盘空间,有几种方法。

如果您有 ZFS 支持并启用重复数据删除,则以前用于存储文件开头(或任何实际部分)数据的块可以通过用零覆盖它们来释放。

fallocate在 Linux 下,您还应该能够通过使用系统调用并向其传递FALLOC_FL_PUNCH_HOLE标志来释放支持稀疏文件(大部分)的文件系统中的部分文件存储。Solaris 提供了类似的fcntl命令F_FREESP。是否fallocatefcntl将有效地工作或根本取决于实施。

或者,如果您运行的操作系统不提供fallocate或等效功能但支持ZFS(例如:FreeBSD),和/或如果重复数据删除不是一个选项,因为您没有足够的 RAM 专用于它,那么轻量级的替代方案就是在文件系统上启用压缩。

于 2013-08-08T20:19:10.767 回答
1

实际上,Linux确实有一个接口可以满足您的要求。要分配的是 FALLOC_FL_COLLAPSE_RANGE 标志。现代内核上的 btrfs、ext4 和 xfs(可能还有其他)支持它。尽管 fallocate 接口允许您指定字节偏移量和长度,但实际上 COLLAPSE_RANGE 调用仅在偏移量和长度是文件系统块大小的倍数时才有效。

有关更多信息,请参阅 fallocate(2) 系统调用的精细手册:http: //man7.org/linux/man-pages/man2/fallocate.2.html

于 2016-08-17T04:20:53.183 回答