Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

1.8K
Vistas
using mmap() to search large file (~1TB)

I'm working on a project that is trying to search for specific bytes (e.g. 0xAB) in a filesystem (e.g. ext2). I was able to find what I needed using malloc(), realloc(), and memchr(), but it seemed slow so I was looking into using mmap(). What I am trying to do is find a specific bytes, then copy them into a struct, so I have two questions: (1) is using mmap() the best strategy, and (2) why isn't the following code working (I get EINVAL error)?

UPDATE: The following program compiles and runs but I still have a couple issues:
1) it won't display correct file size on large files (displayed correct size for 1GB flash drive, but not for 32GB)*.
2) it's not searching the mapping correctly**.

*Is THIS a possible solution to getting the correct size using stat64()? If so, is it something I add in my Makefile? I haven't worked with makefiles much so I don't know how to add something like that.
**Is this even the proper way to search?

#define _LARGEFILE64_SOURCE

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h> 
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char **argv) {

    int fd = open("/dev/sdb1", O_RDONLY); 

    if(fd < 0) {
        printf("Error %s\n", strerror(errno));
        return -1;
    }

    const char * map;   

    off64_t size;
    size = lseek64(fd, 0, SEEK_END);
    printf("file size: %llu\n", size);
    lseek64(fd, 0, SEEK_SET);    

    map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); 
    if (map == MAP_FAILED) { handle_error("mmap error"); }

    printf("Searching for magic numbers...\n");
    for (i=0; i < size; i++) {
    if(map[i] == 0X53 && map[i + 1] == 0XEF) {  
        if ((map[i-32] == 0X00 && map[i-31] == 0X00)  ||            
            (map[i-32] == 0X01 && map[i-31] == 0X00)  ||
            (map[i-32] == 0X02 && map[i-31] == 0X00)) {
            if(j <= 5) { 
                printf("superblock %d found\n", j);
                ++j; 
            } else break;

    int q;
    for(q=0; q<j; q++) {
        printf("SUPERBLOCK[%d]: %d\n", q+1, sb_pos[q]);
    }

    fclose(fd);
    munmap(map, size);
    return 0;
}

Thanks for your help.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

mmap is a very efficient way to handle searching a large file, especially in cases where there's an internal structure you can use (e.g. using mmap on a large file with fixed-size records that are sorted would permit you to do a binary search, and only the pages corresponding to records read would be touched).

In your case you need to compile for 64 bits and enable large file support (and use open(2)).

If your /dev/sdb1 is a device and not a file, I don't think stat(2) will show an actual size. stat returns a size of 0 for these devices on my boxes. I think you'll need to get the size another way.

Regarding address space: x86-64 uses 2^48 bytes of virtual address space, which is 256 TiB. You can't use all of that, but there's easily ~127 TiB of contiguous address space in most processes.

over 4 years ago · Santiago Trujillo Denunciar

0

I just noticed that I was using fopen(), should I be using open() instead?

Yes, you should use open() instead of fopen(). And that's the reason why you got EINVAL error.

fopen("/dev/sdb1", O_RDONLY);

This code is totally incorrect. O_RDONLY is flag that ought to be used with open() syscall but not with fopen() libc functgion

You should also note that mmaping of large files is available only if you are running on a platform with large virtual address space. It's obvious: you should have enough virtual memory to address your file. Speaking about Intel, it should be only x86_64, not x86_32.

I haven't tried to do this with really large files ( >4G). May be some additional flags are required to be passed into open() syscall.

over 4 years ago · Santiago Trujillo Denunciar

0

I'm working on a project that is trying to search for specific bytes (e.g. 0xAB) in a filesystem (e.g. ext2)

To mmap() a large file into memory is totally wrong approach in your case. You just need to process your file step-by-step by chunks with fixed size (something about 1MB). You can use mmap() or just read() it into your intenal buffer - that doesn't matter. But putting a whole file into memory is totally overkill if you just want to process it sequentially.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda