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

发布于 2024-08-10 08:02:56 字数 345 浏览 11 评论 0 原文

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

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

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

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

Before, I post a question here asking for advice on how to read and write data from and into drive, not via file label like "aaa.txt", but just sectors..
I was advised to try read and write....
but new problems'v raised... the hairy parameters

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

when i use the function and wanto read sectors from drive...i seems i need to set the count to be x*512. it has to be several times of 512 bytes...

why??? Are there some raw functions allowing me to use directly byte by byte...
Thanx...
btb, if i wanto do that, I should develope my own I/O driver programs?
thanx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

这个俗人 2024-08-17 08:02:56

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

不要对扇区大小做出假设,您应该查询任何设备的扇区大小,并动态地使用它。硬盘驱动器的典型大小为 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 上获取扇区大小,您可以使用 DeviceIoControl() href="http://msdn.microsoft.com/en-us/library/aa365169%28VS.85%29.aspx" rel="nofollow noreferrer">IOCTL_DISK_GET_DRIVE_GEOMETRY

Stdio 会将搜索与 s 对齐并读取大小为 s 的块。此外,您可以使用 posix_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 中的现有缓冲区中复制出来,而无需访问设备。

Reads and writes to devices must be both sector aligned, and with byte counts that are integer multiples of the sector size.

Don't make assumptions about the sector size, you should query the sector size for any device, and work dynamically with that. Typical sizes are 512 for hard drives, and 2048 for optical drives.

If you want functions that allow you to read byte by byte on devices, without incurring wasteful overhead, try this trick:

FILE *file_pointer = fopen("/path/to/device", "rb");
size_t sector_size;
ioctl(fd, BLKSSZGET, §or_size);
setvbuf(file_pointer, NULL, _IOFBF, sector_size);

If you need to get the sector size on Windows you can call DeviceIoControl() with IOCTL_DISK_GET_DRIVE_GEOMETRY.

Stdio will align seeks to s and read chunks of size s. Additionally you can provide a buffer of your own using posix_memalign(), or _aligned_malloc(), if your underlying stdio implementation doesn't do this.

Edit: To clear up some confusion in a comment

You're working with a device with sector size 512, with FILE *f;. You fseek() to offset 37. f's position is updated, but no seek is made on the device. You fread() 500 bytes. lseek() is called with an offset of 0. 512 bytes are read into f's buffer. Bytes 37 to 512 are copied to the buffer you provided. lseek() is called with an offset of 512. 512 bytes are read, and the remaining 463 bytes you're expecting are copied out to the buffer you passed to fread(). If you were to now fread() a single byte, that would simply be copied out of the existing buffer in f, without hitting the device.

爱的故事 2024-08-17 08:02:56

在这里,我假设您使用 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;
    }

Here, I am assuming you are using linux as the platform. On linux, each device is a file. You will find a device entry in /dev. This means you can do I/O using read/write on that drive e.g. you can directly open your hard disk partition by opening /dev/sda1 and read n number of bytes.

Use following code to determine exact sector size for your drive (no error handling in the code). If you want to read nth sector then just read n*sector_size bytes from the opened device. Hope this helps to solve your problem.

    #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;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文