Недавно я работаю над проектом, которому нужен необработанный сектор чтения/записи дисков.
Вопрос
Ранее я размещал здесь вопрос с просьбой дать совет о том, как читать и записывать данные с диска и на него, не через метку файла, например «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, §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
, не задев устройство.
Другие советы
Я предполагаю, что вы используете 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, §or_size);
printf("%d\n", sector_size);
lseek(fd, n*sector_size, SEEK_SET);
buf = malloc(sector_size);
read(fd, buf, sector_size);
return 0;
}