Недавно я нахожусь на проекте, который нуждается в сыром секторе чтения / записи дисков - PullRequest
1 голос
/ 30 октября 2009

Раньше я публиковал здесь вопрос с просьбой дать совет о том, как читать и записывать данные с диска и на диск, но не через метку файла, например, "aaa.txt", а только через сектора Мне посоветовали попробовать прочитать и написать .... но возникли новые проблемы ... волосатые параметры

int _read( int handle, void *buffer, unsigned int count );

когда я использую функцию и хочу прочитать секторы с диска ... мне кажется, мне нужно установить значение счетчика x * 512. должно быть несколько раз по 512 байт ...

почему ??? Есть ли некоторые необработанные функции, позволяющие мне использовать непосредственно побайтово ... Thanx ... Кстати, если я хочу сделать это, я должен разработать свои собственные программы драйвера ввода-вывода? спасибо

Ответы [ 2 ]

4 голосов
/ 30 октября 2009

Чтение и запись на устройства должны быть как выровнены по секторам, так и с количеством байтов, кратных размеру сектора.

Не делайте предположений о размере сектора, вы должны запросить размер сектора для любого устройства и динамически работать с этим. Типичные размеры: 512 для жестких дисков и 2048 для оптических накопителей.

Если вам нужны функции, позволяющие читать побайтово на устройствах без ненужных затрат, попробуйте этот трюк:

FILE *file_pointer = fopen("/path/to/device", "rb");
size_t sector_size;
ioctl(fd, BLKSSZGET, &sector_size);
setvbuf(file_pointer, NULL, _IOFBF, sector_size);

Если вам нужно получить размер сектора в Windows, вы можете позвонить DeviceIoControl() с IOCTL_DISK_GET_DRIVE_GEOMETRY.

Stdio выровняет запросы к s и считывает куски размером s. Кроме того, вы можете предоставить собственный буфер, используя posix_memalign() или _aligned_malloc(), если ваша базовая реализация stdio этого не делает.

Редактировать: чтобы устранить некоторую путаницу в комментарии

Вы работаете с устройством с размером сектора 512, с FILE *f;. Вы fseek() смещены на 37. Позиция f обновлена, но поиск на устройстве не производится. Вы fread() 500 байтов. lseek() вызывается со смещением 0. 512 байт считываются в буфер f. Байты с 37 по 512 копируются в предоставленный вами буфер. lseek() вызывается со смещением 512. Считывается 512 байт, а остальные 463 байта, которые вы ожидаете, копируются в буфер, который вы передали fread(). Если бы вы сейчас fread() составляли один байт, он просто скопировался бы из существующего буфера в f, не затрагивая устройство.

2 голосов
/ 30 октября 2009

Здесь я предполагаю, что вы используете Linux в качестве платформы. В Linux каждое устройство представляет собой файл. Вы найдете запись устройства в / dev. Это означает, что вы можете выполнять ввод / вывод, используя чтение / запись на этом диске, например, Вы можете напрямую открыть раздел жесткого диска, открыв / dev / sda1 и прочитав n байтов.

Используйте следующий код, чтобы определить точный размер сектора для вашего накопителя (в коде нет обработки ошибок). Если вы хотите прочитать n-й сектор, просто прочитайте n*sector_size байтов с открытого устройства. Надеюсь, это поможет решить вашу проблему.

    #include <stdio.h>
    #include <linux/fs.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    #define SECTOR_NO 10 /*read 10th sector*/

    int main()
    {
            int sector_size;
            char *buf;
            int n = SECTOR_NO;

            int fd = open("/dev/sda1", O_RDONLY|O_NONBLOCK);
            ioctl(fd, BLKSSZGET, &sector_size);
            printf("%d\n", sector_size);
            lseek(fd, n*sector_size, SEEK_SET);

            buf = malloc(sector_size);
            read(fd, buf, sector_size);

            return 0;
    }
...