读取大型二进制文件(2-3 GB)的每30个字节的最快方法是什么?我已经了解到,由于I/O缓冲区的原因,fseek存在性能问题,但我也不希望在每隔30个字节抓取之前将2-3 GB的数据读入内存。
发布于 2010-03-07 07:31:08
我建议您创建一个几千字节的缓冲区,每隔30个字节从其中读取一次,然后用接下来的几千字节重新加载缓冲区,然后继续,直到到达eof。这样,读取到内存的数据量是有限的,而且您也不必经常从文件中读取数据。你会发现你创建的缓冲区越大,它就会越快。
编辑:实际上,按照下面的建议,你可能想把你的缓冲区设置成几百kb,而不是几千字节(就像我说的--更大的缓冲区=更快的文件读取速度)。
发布于 2010-03-07 07:39:21
你可以读取一个字节,然后在一个循环中查找29个字节。但IO子系统必须按扇区读取文件,扇区大小通常为512字节,因此它最终仍将读取整个文件。
从长远来看,只需按步长的倍数分块读取整个文件,然后在缓冲区中查找会更快。如果确保缓冲区大小是30的倍数,并且如果是512的倍数,则可以使fileio子系统的工作变得更简单。
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?
发布于 2010-03-07 07:43:29
如果您愿意打破ANSI-C并使用特定于操作系统的调用,我建议您使用内存映射文件。这是Posix版本(Windows有自己的特定于操作系统的调用):
#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);https://stackoverflow.com/questions/2394479
复制相似问题