之前,我在这里发一个问题,询问如何从驱动器读取和写入数据的建议,而不是通过像“aaa.txt”这样的文件标签,而只是扇区...... 我被建议尝试读写.... 但新问题的提出......毛茸茸的参数
int _read( int handle, void *buffer, unsigned int count );
当我使用该功能并想从驱动器读取扇区时...我似乎需要将计数设置为x * 512。它必须是512字节的几倍......
为什么???是否有一些原始函数允许我逐字节直接使用... 感谢名单... btb,如果我想这样做,我应该开发自己的I / O驱动程序? 感谢名单
答案 0 :(得分:4)
对器件的读写必须是扇区对齐的,并且字节数是扇区大小的整数倍。
不要对扇区大小做出假设,你应该查询任何设备的扇区大小,并动态地使用它。硬盘的典型尺寸为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上获取扇区大小,可以使用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, §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;
}