Считывание и запись на устройства должны быть согласованы по секторам и с подсчетами байтов, которые являются целыми кратными размеру сектора.
Не делайте предположений о размере сектора, вы должны запрашивать размер сектора для любого устройства и работать с ним динамически. Типичные размеры: 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 не делает этого.
Edit: Для того, чтобы прояснить некоторую путаницу в комментарии
Вы работаете с устройством с размером сектора 512, с FILE *f;
. Вы fseek()
на офсетную позицию 37. f
обновляется, но на устройстве не производится поиск. Вы fread()
500 байт. lseek()
вызывается со смещением 0. 512 байт считываются в буфер f
. Байты с 37 по 512 копируются в буфер, который вы предоставили. lseek()
вызывается со смещением 512. Прочитано 512 байт, а остальные 463 байта, которые вы ожидаете, копируются в буфер, который вы передали fread()
. Если бы вы сейчас fread()
один байт, который просто был бы скопирован из существующего буфера в f
, не нажимая на устройство.
Возможно, вы захотите принять некоторые ответы на свои предыдущие вопросы, чтобы люди, которые проводили время, отвечали им, получают определенную награду. –