首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >最快的方式读取每30个字节的大型二进制文件?

最快的方式读取每30个字节的大型二进制文件?
EN

Stack Overflow用户
提问于 2010-03-07 07:28:44
回答 6查看 6.9K关注 0票数 24

读取大型二进制文件(2-3 GB)的每30个字节的最快方法是什么?我已经了解到,由于I/O缓冲区的原因,fseek存在性能问题,但我也不希望在每隔30个字节抓取之前将2-3 GB的数据读入内存。

EN

回答 6

Stack Overflow用户

发布于 2010-03-07 07:31:08

我建议您创建一个几千字节的缓冲区,每隔30个字节从其中读取一次,然后用接下来的几千字节重新加载缓冲区,然后继续,直到到达eof。这样,读取到内存的数据量是有限的,而且您也不必经常从文件中读取数据。你会发现你创建的缓冲区越大,它就会越快。

编辑:实际上,按照下面的建议,你可能想把你的缓冲区设置成几百kb,而不是几千字节(就像我说的--更大的缓冲区=更快的文件读取速度)。

票数 24
EN

Stack Overflow用户

发布于 2010-03-07 07:39:21

你可以读取一个字节,然后在一个循环中查找29个字节。但IO子系统必须按扇区读取文件,扇区大小通常为512字节,因此它最终仍将读取整个文件。

从长远来看,只需按步长的倍数分块读取整个文件,然后在缓冲区中查找会更快。如果确保缓冲区大小是30的倍数,并且如果是512的倍数,则可以使fileio子系统的工作变得更简单。

代码语言:javascript
运行
复制
while (still more file to read)
{ 
   char buf[30 * 512];
   int cread = fread (buf, sizeof(buf), 1, fd);
   for (int ii = 0; ii < cread; ii += 30)
   {

   }
}

这可能看起来效率很低,但它将比尝试读取30字节的区块更快。

顺便说一下。如果您在Windows上运行,并且愿意特定于操作系统,那么内存映射文件的性能将是无与伦比的。How to scan through really huge files on disk?

票数 10
EN

Stack Overflow用户

发布于 2010-03-07 07:43:29

如果您愿意打破ANSI-C并使用特定于操作系统的调用,我建议您使用内存映射文件。这是Posix版本(Windows有自己的特定于操作系统的调用):

代码语言:javascript
运行
复制
#define MAPSIZE 4096
int fd = open(file, O_RDONLY);
struct stat stbuf;
fstat(fd, &stbuf);


char *addr = 0;
off_t last_mapped_offset = -1;
off_t idx = 0;
while (idx < stbuf.st_size)
{
    if (last_mapped_offset != (idx / MAPSIZE))
    {
        if (addr)
            munmap(addr, MAPSIZE);

        last_mapped_offset = idx / MAPSIZE; 

        addr = mmmap(0, MAPSIZE, PROT_READ, MAP_FILE, fd, idx, last_mapped_offset);
    }

    *(addr + (idx % MAPSIZE));

    idx += 30;

}

munmap(addr, MAPSIZE);
close(fd);
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2394479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档