【问题标题】:MapViewOfFile read from a given positionMapViewOfFile 从给定位置读取
【发布时间】:2020-07-23 23:24:57
【问题描述】:

我需要将一个大文件部分读取到有限的缓冲区中。我的代码有效,但总是从头开始读取。我想我需要以某种方式使用 dwFileOffsetHigh 和 dwFileOffsetLow,但我不知道如何。 Mapper_Winapi_Uptr 是一个带有自定义删除器的 unique_ptr,如有必要,我可以布置它的代码。 系统:64位Win10。

const std::vector<BYTE>& ReadFile(size_t pos) {

    memory = Mapper_Winapi_Uptr{ static_cast<BYTE*>(MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, bufferSize)) };
    std::memcpy(&data[0], memory.get(), bufferSize);
    return data;
}

【问题讨论】:

  • docs 解释了如何使用这些参数。您具体遇到了什么问题?
  • 我阅读了文档但不明白这些参数之间的区别以及如何使用它们。
  • 文件偏移是一个64位的值,分成两个32位的值。

标签: c++ winapi memory mapping c++17


【解决方案1】:

您在文件偏移量 0 处映射视图,忽略您的 pos 参数,这可能是所需的文件偏移量。

MapViewOfFile() 将 64 位偏移量作为输入,分为 32 位低值和高值。 size_t 可能是 32 位或 64 位类型,具体取决于编译器和平台。您可以先将所需的偏移量放入ULARGE_INTEGER,这将为您提供低值和高值,然后您可以将其提供给MapViewOfFile()

请注意,您给MapViewOfFile() 的文件偏移量必须是系统分配粒度的倍数。有关如何处理的详细信息,请参阅 MSDN 上的 Creating a View Within a File

试试这样的:

SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD SysGran = SysInfo.dwAllocationGranularity;
... 
const std::vector<BYTE>& ReadFile(size_t pos)
{
    size_t MapViewStart = (pos / SysGran) * SysGran;
    DWORD MapViewSize = (pos % SysGran) + bufferSize;
    DWORD ViewDelta = pos - MapViewStart;

    ULARGE_INTEGER ulOffset;
    ulOffset.QuadPart = MapViewStart;
    memory = Mapper_Winapi_Uptr{ static_cast<BYTE*>(MapViewOfFile(mapping, FILE_MAP_READ, ulOffset.HighPart, ulOffset.LowPart, bufferSize)) };
    if (!memory.get()) {
        // error handling ...
    }

    std::memcpy(&data[0], &(memory.get())[ViewDelta], bufferSize);
    return data;
}

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多