【问题标题】:C++ sector aligned readC++ 扇区对齐读取
【发布时间】:2017-07-06 10:51:29
【问题描述】:

我问这个是因为当我们读取原始设备时我无法理解扇区对齐的读取。

让我们假设在 Windows 机器中,我们使用 ReadFile() C 函数从设备读取 x 字节。

我知道我们只能读取扇区对齐的数据,但最近我发现了 SetFilePointer() 函数,它允许我们将指针放在我们之前用 CreateFile() 打开的设备的 x 字节中。

我的问题是,如果我们需要读取扇区对齐的数据,如果我们使用SetFilePointer(),例如这样:

SetFilePointer(device, 12, NULL, FILE_BEGIN);

(设备是一个现有设备的HANDLE,为了这个例子,我们假设它是一个USB笔驱动器),在那个例子中,我们设置了一个指向从FILE_BEGIN开始的第12个字节的指针。

如果我要从第 12 个字节开始读取相当于一个扇区(512 个字节),我是否需要像这样进行读取功能:

ReadFile(device, sector, (512 - 12), &bytesRead, NULL)

或者像这样:

ReadFile(device, sector, 512, &bytesRead, NULL)

无论如何,谢谢!

【问题讨论】:

    标签: c++ windows readfile


    【解决方案1】:

    我的问题是,如果我们需要读取扇区对齐的数据,如果我们使用SetFilePointer(),例如这样:

    SetFilePointer(device, 12, NULL, FILE_BEGIN);
    

    ... 那么您将不再读取扇区对齐的数据,并且您将在 ReadFile 调用中收到错误 87。读取扇区对齐的数据不仅意味着您必须读取扇区大小的块,而且您必须始终读取从扇区边界开始的块。

    您必须寻找包含您感兴趣的字节的扇区(因此,position/sector_size*sector_size),读取整个扇区并从您读取的数据中提取您感兴趣的字节。

    【讨论】:

    • 所以我可以使用SetFilePointer() 指向任何内容,但如果SetFilePointer() 不是指向扇区的开头,我就不能使用ReadFile()
    • 是的;一般来说,如果您在原始设备上工作,则寻求未对齐的位置是没有意义的。
    • @MatteoItalia 我在一个项目中尝试过这个,例如,如果我将SetFilePointer() 放在 40 中,并使用 ReadFile() 512 个字节,它可以工作,为什么会这样?它不应该给我一个错误,因为我读取了扇区顺序吗?
    • 这取决于驱动程序或设备的感觉,但不支持,如我之前答案中的链接中所述。它可能会起作用,但这只是运气,更改设备或Windows版本或驱动程序或其他任何东西,它就不再起作用了。遵守规则,你不会有问题。
    • @jeyejow:你和drk是同一个用户吗?
    【解决方案2】:

    好吧,这取决于..

    • 如果您希望缓冲区中的内容代表设备的整个扇区,并使用 struct* 或字节偏移量进行映射 - 通常就是这样做的。那么您发送到 SetFilePointer 的偏移量应该与扇区大小对齐,然后读取扇区大小的缓冲区。所以 SetFilePointer(0) -> ReadFile(512 bytes)

    • 如果你不关心,只需要字节 12-16,SetFilePointer(12) -> Read(4bytes)。

    我会选择解决方案 1,因为从长远来看,它可能会使代码更易于阅读和维护。

    【讨论】:

    • 但您只能使用 ReadFile() 并一次读取扇区对齐的字节,例如 512、1024 等
    • 那么,未对齐的 SetFilePointers() 也会失败。
    猜你喜欢
    • 2015-09-29
    • 2011-11-09
    • 2020-10-11
    • 2019-04-25
    • 2013-07-16
    • 1970-01-01
    • 2015-06-17
    • 2013-07-15
    • 2010-12-17
    相关资源
    最近更新 更多