Я работаю над проектом, который пытается найти конкретные байты (например, 0xAB) в файловой системе (например, ext2). Я смог найти то, что мне нужно, используя malloc()
, realloc()
и memchr()
, но это казалось медленным, поэтому я искал использование mmap()
. То, что я пытаюсь сделать, это найти конкретные байты, а затем скопировать их в структуру, поэтому у меня есть два вопроса: (1) использует mmap()
наилучшую стратегию и (2) почему не работает следующий код (я получаю Ошибка EINVAL)?using mmap() для поиска по большому счёту (~ 1TB)
UPDATE: Следующая программа компилируется и работает, но я до сих пор есть несколько вопросов:
1) не будет отображаться правильный размер файла на больших файлов (отображается правильный размер для флэш-накопитель 1 ГБ, но не для 32 Гб) * ,
2) он неправильно искажает отображение **.
* THIS Возможное решение для получения правильного размера с помощью stat64()
? Если да, то что-то я добавляю в свой Makefile? Я не работал с make-файлами, поэтому не знаю, как добавить что-то подобное.
** Это даже правильный способ поиска?
#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;
}
Благодарим за помощь.
вы должны проверить переменную errno, чтобы понять, почему mmap не удалось –
Вы читали [ЭТО] (http://stackoverflow.com/questions/10088962/mmap-returns-einval) вопрос? – Shark
Вероятно, он не работает, потому что он не может найти непрерывную полосу памяти с запрошенной длиной ('size'). – Shark