1

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

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

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

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

4

2 回答 2

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并读取 size 块sposix_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,而不会影响设备。

于 2009-10-30T10:47:36.187 回答
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;
    }
于 2009-10-30T12:41:45.737 回答