Недавно я работаю над проектом, которому нужен необработанный сектор чтения/записи дисков.

StackOverflow https://stackoverflow.com/questions/1648943

  •  22-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

Не делайте предположений о размере сектора, вам следует запрашивать размер сектора для любого устройства и динамически работать с ним.Типичные размеры — 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, не задев устройство.

Другие советы

Я предполагаю, что вы используете 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;
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top