暴力查找 FILE* C
Brute-forcing find FILE* C
我一直在寻找一种在 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,因为我的目标是在一个大到 60gigs 的文件中找到它们,而且那个文件中可能有几十万个
备份和 re-reading 数据会大大降低速度。
基于@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!
}
}
为清楚起见,省略了错误检查和正确 headers。
有很多方法可以提高它的性能。这种 IO 模式是 最差 可能使用 mmap()
的性能 - 只读取文件中的每个字节一次,然后丢弃映射。因为首先映射一个文件并不是那么快,而且它会影响整个机器。
如果只使用 open()
和 read()
直接 IO 大 page-sized 块到 page-aligned 内存,特别是如果文件是系统 RAM 的很大一部分。但这会使代码复杂得多,因为比较必须跨越缓冲区——使用两个缓冲区并复制几个字节来搜索缓冲区之间的中断几乎肯定比备份和执行一个要快得多non-aligned 已读。
我一直在寻找一种在 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,因为我的目标是在一个大到 60gigs 的文件中找到它们,而且那个文件中可能有几十万个
备份和 re-reading 数据会大大降低速度。
基于@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!
}
}
为清楚起见,省略了错误检查和正确 headers。
有很多方法可以提高它的性能。这种 IO 模式是 最差 可能使用 mmap()
的性能 - 只读取文件中的每个字节一次,然后丢弃映射。因为首先映射一个文件并不是那么快,而且它会影响整个机器。
如果只使用 open()
和 read()
直接 IO 大 page-sized 块到 page-aligned 内存,特别是如果文件是系统 RAM 的很大一部分。但这会使代码复杂得多,因为比较必须跨越缓冲区——使用两个缓冲区并复制几个字节来搜索缓冲区之间的中断几乎肯定比备份和执行一个要快得多non-aligned 已读。