如何从文件中读取数据块,然后从该块读入向量

How to read blocks of data from a file and then read from that block into a vector?

本文关键字:然后 向量 数据 文件 读取      更新时间:2023-10-16

假设我有一个文件,它有x条记录。一个"块"保存m条记录。文件n=x/m的总块数。如果我知道一条记录的大小,比如b字节(一个块的大小= b*m),我可以使用系统命令read()立即读取整个块(还有其他方法吗?)。现在,我如何从这个块中读取每条记录,并将每条记录作为单独的元素放入向量中?

我想这样做的原因首先是为了减少磁盘I/o操作。因为据我所知,磁盘i/o操作要昂贵得多。或者它会花费相同的时间,当我从文件中逐条读取记录,并直接将其放入向量,而不是读取块逐块?如果一个块一个块地读取,我将只有n个磁盘I/O,而如果我一个记录一个记录地读取,我将有x个I/O。

谢谢。

您应该考虑使用mmap()而不是使用read()来读取文件。

关于mmap的好处是,您可以将文件内容简单地映射到您的进程空间,就好像您已经有一个指向文件内容的指针一样。通过简单地检查内存内容并将其作为数组处理,或者通过使用memcpy()复制数据,您将隐式地执行读取操作,但仅在必要时—操作系统虚拟内存子系统足够聪明,可以非常有效地完成操作。

避免mmap的唯一可能原因可能是如果您在32位操作系统上运行并且文件大小超过2 gb(或略小于2 gb)。在这种情况下,操作系统可能在为mmap -ed内存分配地址空间时遇到麻烦。但是在64位操作系统上使用mmap应该不会有问题。

此外,如果您正在写入大量数据,并且事先不知道数据的大小,mmap可能会很麻烦。除此之外,使用它总是比使用read更好更快。

实际上,大多数现代操作系统都广泛依赖于mmap。例如,在Linux中,要执行一些二进制文件,您的可执行文件只需mmap -ed并从内存中执行,就好像它是由read复制到那里的,而实际上没有read

一次读取一个块并不一定会减少I/O操作的数量。标准库已经在从文件中读取数据时进行了缓冲,因此(通常)期望每次尝试从流(或任何接近流的东西)读取时都看到实际的磁盘输入操作。

仍然有可能一次读取一个块来减少I/O操作的数量。如果您的块大于默认情况下流使用的缓冲区,那么您将期望看到用于读取数据的I/O操作更少。另一方面,您可以通过简单地调整流使用的缓冲区大小来实现相同的目的(这可能要简单得多)。

相关文章: