2009-10-30 7 views
1

Прежде чем, я размещаю здесь вопрос о том, как читать и записывать данные с диска и на диск, а не через метку файла, например «aaa.txt », но только сектора .. мне посоветовали попробовать читать и писать .... но новые problems'v подняли ... волосатые параметрыВ последнее время я нахожусь в проекте, который нуждается в необработанном секторе чтения/записи приводов.

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

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

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

+4

Возможно, вы захотите принять некоторые ответы на свои предыдущие вопросы, чтобы люди, которые проводили время, отвечали им, получают определенную награду. –

ответ

4

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

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

Edit: Для того, чтобы прояснить некоторую путаницу в комментарии

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

+1

, но все равно вам придется выдать fread/fwrite с номером байта как параметр, не так ли? Это не решает эту проблему. Как вы сказали, он сначала должен определить размер сектора своего диска, а затем прочитать данные n * sector_size для чтения n-го сектора. Поправьте меня, если я ошибаюсь. –

+1

Вы ошибаетесь. : P точка за кулисами stdio выполняет буферизацию, которая включает в себя чтение целых кусков размера s, а затем только предоставление частей, которые вы просили. –

+2

точно, например. первый 1 байт-файл фактически не будет читать байтов, заданных setvbuf (размер сектора в вашем коде), но он предоставит только один байт для приложения. Таким образом, чтобы прочитать полный сектор, приложение должно будет выполнить fread размера сектора. Теперь, чтобы определить точный размер сектора, приложение сначала должно будет выпустить ioctl (BLKSSZGET). Я думаю, это то, чего хочет Макроидеал, чтобы он мог делать I/O с точки зрения сектора. –

2

Здесь я предполагаю, что вы используете 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; 
    }