之前,我在这里发布了一个问题,寻求有关如何从驱动器读取数据和将数据写入驱动器的建议,而不是通过“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
发布评论
评论(2)
对设备的读取和写入必须是扇区对齐的,并且字节计数是扇区大小的整数倍。
不要对扇区大小做出假设,您应该查询任何设备的扇区大小,并动态地使用它。硬盘驱动器的典型大小为 512,光盘驱动器的典型大小为 2048。
如果您想要允许您在设备上逐字节读取的函数,而不会产生浪费的开销,请尝试以下技巧:
如果您需要在 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:
If you need to get the sector size on Windows you can call
DeviceIoControl()
withIOCTL_DISK_GET_DRIVE_GEOMETRY
.Stdio will align seeks to
s
and read chunks of sizes
. Additionally you can provide a buffer of your own usingposix_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;
. Youfseek()
to offset 37.f
's position is updated, but no seek is made on the device. Youfread()
500 bytes.lseek()
is called with an offset of 0. 512 bytes are read intof
'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 tofread()
. If you were to nowfread()
a single byte, that would simply be copied out of the existing buffer inf
, without hitting the device.在这里,我假设您使用 Linux 作为平台。在linux上,每个设备都是一个文件。您将在 /dev 中找到一个设备条目。这意味着您可以在该驱动器上使用读/写来执行 I/O,例如您可以通过打开 /dev/sda1 并读取 n 个字节来直接打开硬盘分区。
使用以下代码确定驱动器的确切扇区大小(代码中没有错误处理)。如果您想读取第 n 个扇区,则只需从打开的设备中读取
n*sector_size
字节即可。希望这有助于解决您的问题。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.