Windows 最近,我参加了一个项目,该项目需要驱动器的原始读/写扇区

Windows 最近,我参加了一个项目,该项目需要驱动器的原始读/写扇区,windows,linux,file-io,sector,Windows,Linux,File Io,Sector,在此之前,我在这里发布了一个问题,询问如何从驱动器中读写数据,而不是通过“aaa.txt”这样的文件标签,而是通过扇区。。 有人建议我试着读和写。。。。 但新问题的提出。。。毛茸茸的参数 int\u读取(int句柄、void*缓冲区、无符号int计数) 当我使用函数和WAN从驱动器读取扇区时…我似乎需要将计数设置为x*512。它必须是512字节的几倍 为什么???是否有一些原始函数允许我直接逐字节使用。。。 Thanx。。。 顺便说一句,如果我想这样做,我应该开发自己的i/O驱动程序? than

在此之前,我在这里发布了一个问题,询问如何从驱动器中读写数据,而不是通过“aaa.txt”这样的文件标签,而是通过扇区。。 有人建议我试着读和写。。。。 但新问题的提出。。。毛茸茸的参数

int\u读取(int句柄、void*缓冲区、无符号int计数)

当我使用函数和WAN从驱动器读取扇区时…我似乎需要将计数设置为x*512。它必须是512字节的几倍

为什么???是否有一些原始函数允许我直接逐字节使用。。。 Thanx。。。 顺便说一句,如果我想这样做,我应该开发自己的i/O驱动程序?
thanx对设备的读写必须是扇区对齐的,并且字节计数必须是扇区大小的整数倍

不要对扇区大小进行假设,您应该查询任何设备的扇区大小,并动态地使用它。硬盘驱动器的典型尺寸为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()

Stdio将对齐搜索到
s
并读取大小为
s
的块。此外,如果底层stdio实现不这样做,您可以使用或提供自己的缓冲区

编辑:清除评论中的一些混乱


您正在使用扇区大小为512的设备,使用
FILE*f。您将
fseek()
设置为偏移量37
f
的位置已更新,但未在设备上进行寻道。您可以
fread()
500字节<调用code>lseek()
时偏移量为0。512字节被读入
f
的缓冲区。字节37到512将复制到您提供的缓冲区<调用code>lseek()
时偏移量为512。读取512字节,剩余的463字节将复制到传递给
fread()
的缓冲区中。如果您现在使用
fread()
单个字节,则只需将其从
f
中的现有缓冲区中复制出来,而不会命中设备。

对设备的读写必须是扇区对齐的,并且字节计数必须是扇区大小的整数倍

不要对扇区大小进行假设,您应该查询任何设备的扇区大小,并动态地使用它。硬盘驱动器的典型尺寸为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()

Stdio将对齐搜索到
s
并读取大小为
s
的块。此外,如果底层stdio实现不这样做,您可以使用或提供自己的缓冲区

编辑:清除评论中的一些混乱


您正在使用扇区大小为512的设备,使用
FILE*f。您将
fseek()
设置为偏移量37
f
的位置已更新,但未在设备上进行寻道。您可以
fread()
500字节<调用code>lseek()
时偏移量为0。512字节被读入
f
的缓冲区。字节37到512将复制到您提供的缓冲区<调用code>lseek()时偏移量为512。读取512字节,剩余的463字节将复制到传递给
fread()
的缓冲区中。如果您现在使用
fread()
一个字节,则只需将其从
f
中的现有缓冲区中复制出来,而不必点击设备。

这里,我假设您使用linux作为平台。在linux上,每个设备都是一个文件。您将在/dev中找到一个设备条目。这意味着您可以在该驱动器上使用读/写操作进行I/O,例如,您可以通过打开/dev/sda1并读取n个字节来直接打开硬盘分区

使用以下代码确定驱动器的确切扇区大小(代码中没有错误处理)。如果要读取第n个扇区,则只需从打开的设备读取
n*扇区大小
字节。希望这有助于解决您的问题

    #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;
    }
#包括
#包括
#包括
#包括
#包括
#定义扇区号10/*为第10扇区*/
int main()
{
int扇区大小;
char*buf;
int n=扇区号;
int fd=open(“/dev/sda1”,O|RDONLY | O|unblock);
ioctl(fd、BLKSSZGET和扇区大小);
printf(“%d\n”,扇区大小);
lseek(fd,n*扇区大小,搜索集);
buf=malloc(扇区大小);
读取(fd、buf、扇区大小);
返回0;
}

在这里,我假设您使用linux作为平台。在linux上,每个设备都是一个文件。您将在/dev中找到一个设备条目。这意味着您可以在该驱动器上使用读/写操作进行I/O,例如,您可以通过打开/dev/sda1并读取n个字节来直接打开硬盘分区

使用以下代码确定驱动器的确切扇区大小(代码中没有错误处理)。如果要读取第n个扇区,则只需从打开的设备读取
n*扇区大小
字节。希望这有助于解决您的问题

    #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;
    }
#包括
#包括
#包括
#包括
#包括
#定义扇区号10/*为第10扇区*/
int main()
{
int扇区大小;
char*buf;
int n=扇区号;
int fd=open(“/dev/sda1”,O|RDONLY | O|unblock);
ioctl(fd、BLKSSZGET和扇区大小);
printf(“%d\n”,扇区大小);
lseek(fd,n*扇区大小,搜索集);
buf=malloc(扇区大小);
读取(fd、buf、扇区)