我一直在寻找一种方法来强制在C文件中查找int64_t。 我写了以下代码。
int64_t readbyte = 0, totalreadbytes = 0;
int64_t totalfound = 0;
const int64_t magic = MAGIC_NUMBER;
char *buffer = (char *)malloc(BUFFER_SIZE);
int64_t *offsets = (int64_t *)malloc(sizeof(int64_t) * (1 << 24));
if (buffer == NULL || offsets == NULL)
{
return -3;
}
while ((readbyte = fread(buffer, 1, BUFFER_SIZE, inptr)) > 0)
{
for (int i = 0; i <= readbyte - 8; i++)
{
if (memcmp(buffer + i, &magic, sizeof(magic))==0)
{
offsets[totalfound++] = totalreadbytes + i;
}
}
totalreadbytes += readbyte - 8;
fseek(inptr, -8, SEEK_CUR);
}
// Do something to those offsets found
free(offsets);
free(buffer);
我一直想知道是否有更好的方法来找到int64_t,因为我的目标是在一个大到60gig的文件中找到它们,并且该文件中可能有几十万个
答案 0 :(得分:1)
备份和重新读取数据会使事情变得缓慢。
在@melpomene评论的基础上,这是使用mmap()
进行此操作的一种非常简单的方法:
uint64_t needle;
struct stat sb;
int fd = open( filename, O_RDONLY );
fstat( fd, &sb );
unsigned char *haystack = mmap( NULL, sb.st_size,
PROT_READ, MAP_PRIVATE, fd, 0 );
close( fd );
off_t bytesToSearch = sb.st_size - sizeof( needle );
// <= so the last bytes get searched
for ( off_t ii = 0; ii <= bytesToSearch; ii++ )
{
if ( 0 == memcmp( haystack + ii, &needle, sizeof( needle ) ) )
{
// found it!
}
}
为清晰起见,错误检查和正确的标题被省略。
有很多方法可以改善其性能。这个IO模式是关于性能的{strong>最差可能使用mmap()
- 只读取文件中的每个字节一次,然后抛出映射。因为映射文件的速度并不快,所以它会影响整个机器。
使用open()
和read()
将大页面大小的块中的直接IO用于页面对齐的内存,尤其是 lot 可能更快批次如果文件是系统RAM的重要部分。但这会使代码变得更复杂,因为比较必须跨越缓冲区 - 使用两个缓冲区并复制几个字节来搜索缓冲区之间的中断几乎肯定要快得多。起来并进行不对齐的阅读。