假设我有一个包含x条记录的文件。一个'块'包含m个记录。文件中的块总数n = x / m。如果我知道一个记录的大小,比如b字节(一个块的大小= b * m),我可以使用系统命令read()一次读取整个块(是否还有其他方法?)。现在,如何从该块中读取每条记录,并将每条记录作为单独的元素放入向量中。
我首先想要这样做的原因是减少磁盘I / O操作。根据我所学到的,磁盘I / O操作要贵得多。 或者它会花费相同的时间,当我从文件中读取记录并直接将其放入向量而不是逐块读取时?在逐块读取时,如果我按记录读取记录,我将只有n个磁盘I / O而x I / O.
感谢。
答案 0 :(得分:3)
您应该考虑使用mmap()
而不是使用read()
来阅读文件。
mmap
的好处在于,您可以将文件内容简单地映射到您的进程空间,就好像您已经有一个指向文件内容的指针一样。通过简单地检查内存内容并将其视为数组,或者使用memcpy()
复制数据,您将隐式执行读取操作,但仅在必要时 - 操作系统虚拟内存子系统足够智能,可以非常有效地执行操作。
如果您在32位操作系统上运行并且文件大小超过2千兆字节(或稍微小于该值),则唯一可能的原因是避免使用mmap。在这种情况下,操作系统可能无法为您的mmap
内存分配地址空间。但是在使用mmap
的64位操作系统上永远不应该成为问题。
此外,如果您要编写大量数据,mmap
可能很麻烦,并且数据的大小不是预先知道的。除此之外,在read
上使用它总是更好更快。
实际上,大多数现代操作系统都广泛依赖mmap
。例如,在Linux中,为了执行某些二进制文件,您的可执行文件只是mmap
- 从内存执行并执行,就好像它是read
复制的那样,而不是实际read
。< / p>
答案 1 :(得分:2)
一次读取一个块不一定会减少I / O操作的数量。标准库在从文件中读取数据时已经进行了缓冲,因此每次尝试从流中读取(或任何接近的)时,不(通常)都希望看到实际的磁盘输入操作
一次读取一个块仍然可以减少I / O操作的数量。如果您的块大于默认情况下流使用的缓冲区,那么您希望看到用于读取数据的I / O操作更少。另一方面,您可以通过简单地调整流使用的缓冲区大小来实现相同的目标(这可能更容易)。