Чтение и запись на устройства должны быть как выровнены по секторам, так и с количеством байтов, кратных размеру сектора.
Не делайте предположений о размере сектора, вы должны запросить размер сектора для любого устройства и динамически работать с этим. Типичные размеры: 512 для жестких дисков и 2048 для оптических накопителей.
Если вам нужны функции, позволяющие читать побайтово на устройствах без ненужных затрат, попробуйте этот трюк:
FILE *file_pointer = fopen("/path/to/device", "rb");
size_t sector_size;
ioctl(fd, BLKSSZGET, §or_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
, не затрагивая устройство.