11

假设目的是在运行 Linux 的嵌入式设备上创建一个开头有一个大洞的文件,稍后我们将写入该文件。我们打开文件,获取文件描述符并调用lseek它来寻找某个已知位置。之后,当我们想在寻找到的位置写入该文件时,我们调用write它。

但是,在第一次写入时,通过查找创建的空洞会被零填充,如果空洞足够大,此操作可能需要一些时间。在我的应用程序中,不需要这种零初始化,因为孔的长度是准确的,稍后我将用我的数据填充它。

有没有办法避免在零填充漏洞write后进行第一次调用seek(即使它涉及修改文件系统驱动程序)?或者,有没有办法在文件开头(附加到文件的前面)之前写入文件?

4

4 回答 4

8

这可能与您的文件系统有关。在 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

在您的文件系统上,这可能会失败。如果是这样,并且您需要创建一个稀疏文件,请确定您是否可以使用不同的文件系统。

于 2016-02-01T00:05:47.030 回答
1

但是,在第一次写入时,通过查找创建的空洞会被零填充,如果空洞足够大,此操作可能需要一些时间。

不,它不能。它只会将您提供的数据写入write(). 未写入部分中的零实际上并不存在:它们是文件系统的产物。

于 2016-02-01T00:06:21.767 回答
0

This may not be a feasible solution for your use case for various reasons, but I can imagine splitting the large file into serially numbered chunks. A missing or zero-sized chunk is supposed to contain zeroes (or some other fixed value). Choose the chunk size to fit the space you want to reserve and to get a good compromise between file size and number of chunks.

Or make it a bit more complicated and use variable chunk sizes, with the "virtual" size of the individual chunk stored somewhere else. Given a complex enough numbering system you can even insert new chunks without renaming the subsequent chunk files...

Of course you'll need an additional access layer to do the de-chunking, either in your application code if that's sufficient, or worst-case as kernel driver hooking into the file handling.

于 2016-02-03T15:29:38.497 回答
-1

您是否尝试过使用标志MAP_UNINITIALIZED

于 2016-01-31T23:56:37.210 回答