最近,我正在进行一个需要驱动器的原始读/写扇区的项目

时间:2009-10-30 10:09:06

标签: windows linux file-io sector

之前,我在这里发一个问题,询问如何从驱动器读取和写入数据的建议,而不是通过像“aaa.txt”这样的文件标签,而只是扇区...... 我被建议尝试读写.... 但新问题的提出......毛茸茸的参数

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

当我使用该功能并想从驱动器读取扇区时...我似乎需要将计数设置为x * 512。它必须是512字节的几倍......

为什么???是否有一些原始函数允许我逐字节直接使用... 感谢名单... btb,如果我想这样做,我应该开发自己的I / O驱动程序? 感谢名单

2 个答案:

答案 0 :(得分: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上获取扇区大小,可以使用IOCTL_DISK_GET_DRIVE_GEOMETRY致电DeviceIoControl()

Stdio会将搜索对齐s并读取大小为s的块。此外,如果基础stdio实现不这样做,您可以使用posix_memalign()_aligned_malloc()提供自己的缓冲区。

编辑:澄清评论中的一些混淆

您正在使用扇区大小为512且FILE *f;的设备。您fseek()要偏移37. f的位置已更新,但未在设备上进行搜索。你fread() 500字节。调用lseek()时偏移量为0. 512字节被读入f的缓冲区。将字节37到512复制到您提供的缓冲区。调用lseek()时偏移量为512.读取512字节,并将剩余的463个字节复制到传递给fread()的缓冲区。如果您现在要fread()一个字节,那么只需将其复制到f中的现有缓冲区中,而无需点击该设备。

答案 1 :(得分:2)

在这里,我假设你使用linux作为平台。在linux上,每个设备都是一个文件。您将在/ dev中找到设备条目。这意味着您可以使用该驱动器上的读/写来执行I / O操作,例如您可以通过打开/ 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;
    }