假设我们的目的是在开始的时候创build一个有大漏洞的文件,我们将在后面写一个运行Linux的embedded式设备。 我们打开这个文件,获得一个文件描述符,并调用lseek
来寻找一个确定的已知位置。 之后,当我们想要在寻找位置上写入该文件时,我们称之为write
。
但是,在第一次写入时,寻求创build的空洞将被填满,如果空洞足够大,此操作可能需要一些时间。 在我的应用程序中,没有必要进行这种零初始化,因为这个孔的长度是确切的,我将在稍后填入我的数据。
是否有一种方法可以避免在seek
零填充(即使涉及到修改文件系统驱动程序)之后进行第一次write
调用? 或者,在文件开始之前是否有写入文件的方法(追加到文件的前面)?
这可能与您的文件系统有关。 在ext2 / 3/4上,reiser,btrfs,xfs等等,做你所描述的不应该花很长时间,因为它们支持所谓的“稀疏文件”(在底层存储中占用的空间少于文件的大小,因为零的运行没有物理存储)。
你可以用dd
来试验一下,以确保是这样的:
$ dd if=/dev/zero of=whatever bs=1k seek=1073741824 count=1 1+0 records in 1+0 records out 1024 bytes (1.0 kB) copied, 9.1878e-05 s, 11.1 MB/s $ ls -al whatever -rw-r--r-- 1 xxxx xxxx 1099511628800 Jan 31 18:04 whatever $ du -h whatever 16K whatever
在你的文件系统上,可能会失败。 如果是这样,并且您需要创建一个稀疏文件,请确定您是否可以使用不同的文件系统。
但是,在第一次写入时,寻求创建的空洞将被填满,如果空洞足够大,此操作可能需要一些时间。
不,它不能。 它只会写入你提供给write()
的数据。 未写入部分中的零不是物理上的:它们是文件系统的人造物。
这可能不是一个可行的解决方案,因为各种原因你的用例,但我可以想象将大文件分割成连续编号的块。 缺失或零大小的块应该包含零(或其他固定值)。 选择块大小以适合您要保留的空间,并在文件大小和块数之间取得妥协。
或者使它更复杂一些,并使用可变的块大小,其中个别块的“虚拟”大小存储在其他地方。 给定一个复杂的编号系统,你甚至可以插入新的块,而不用重命名后续的块文件。
当然,你需要一个额外的访问层来完成分块,如果足够了,或者作为内核驱动程序挂钩到文件处理的最坏情况。
你有没有尝试使用标志MAP_UNINITIALIZED ?