使用 fseek 和 fread

4

我正在处理一个从二进制文件中读取并处理数据的项目。这个二进制文件非常大,大约有150MB。我正在尝试使用fseek来跳过不需要处理的数据。

我想知道fseek的处理时间是否与fread相同。

谢谢!


fseek 应该比 fread 快得多,因为它只是移动指针。 - Ilia Frenkel
4个回答

3

fseek 仅重新定位内部文件指针,而 fread 实际读取数据。因此,我认为 fseek 应该比 fread 快得多。

如果你真的想知道屏幕后面发生了什么,请从这里下载 glibc 并自己查看 :)


0
我在想,fseek 的处理时间是否与 fread 相同。
虽然这可能是实现相关的,但很可能 fseek 只会设置一个内存中的“文件指针”,而不会读取任何信息。另一方面,fread 会读取信息。
在进行一个指向文件位置 149M 的 fseek 后,再进行一个 1M 的 fread,可能比进行 150 次不同的 1M fread 调用更快,且只保留最后一个。

0

我认为fseek可能比fread快一点,因为fseek会将指针位置更改到您提到的新地址空间,并且没有进行数据读取。


0
如果您正在处理大文件,是否考虑过替代的读写方式?您可能会发现mmap()(UNIX)或MapViewOfFile(Windows)是更合适的选择。以下是一个UNIX示例,演示了打开一个文件进行读取并计算ASCII字符“Q”的出现次数。注意-为了缩短示例,所有错误检查都已省略。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>


int main(int argc, char **argv)
{
  int i, fd, len, total;
  char *map, *ptr;

  fd = open("/tmp/mybigfile", O_RDONLY);

  len = lseek(fd, SEEK_END, 0);

  map = (char *)mmap(0, len, PROT_READ, MAP_SHARED, fd, 0);

  total = 0;
  for (i=0; i<len; i++) {
    if (map[i] == 'Q') total++;
  }

  printf("Found %d instances of 'Q'\n");

  munmap(map, len);

  close(fd);
}

当您添加性能数据以比较普通的fread fseek时,此答案将会很有帮助。 - Pavan Manjunath
fseek()和fread()操作是库调用,由read()和lseek()系统调用支持。 fstream函数族将使用缓冲IO来提高性能,但仍需要在某些时候进行系统调用。 mmap()调用是一个单一的系统调用,依赖于操作系统的分页缓冲区来代表您从磁盘读取和写入数据。如果您发现使用这种方法比fread()更快,我会感到惊讶。 - Angelom
从您之前发布的帖子中,我猜测您正在处理一些二进制数据文件。如果数据是在相同平台上以匹配的字节序写入的,那么使用mmap()读取固定大小的字段并将其写入文件是非常简单的。只需将结构体覆盖在您期望在映射中找到它的位置上,并直接从结构体中读取即可。 - Angelom
我的意图是通过添加性能数据,让OP和其他人更倾向于这种方法(你知道数字比事实更有说服力 : ) ),从而使您的回答变得更加有用。 - Pavan Manjunath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接