代码之家  ›  专栏  ›  技术社区  ›  Mian Bilawal

强制查找文件*C

  •  -1
  • Mian Bilawal  · 技术社区  · 7 年前

    我一直在寻找一种方法来强制在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的文件中找到它们,并且在该文件中可能有几十万个

    1 回复  |  直到 7 年前
        1
  •  1
  •   Andrew Henle    7 年前

    备份和重新读取数据会使速度大大降低。

    基于@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模式是 最差的 可能使用 mmap() 就性能而言,只需读取文件中的每个字节一次,然后丢弃映射。因为映射文件一开始并不那么快,它会影响整个机器。

    可能是 大量 使用起来更快 open() read() 将大页面大小的块中的直接IO放入页面对齐的内存中,尤其是当文件占系统RAM的很大一部分时。但这将使代码更加复杂,因为比较必须跨越缓冲区-几乎可以肯定,使用两个缓冲区并复制几个字节来搜索缓冲区之间的断点要比备份和执行非对齐读取快得多。