You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何使用Windows API ReadFile()从指定偏移位置读取文件

问题说明

以下C#代码片段可实现对二进制文件的分页顺序读取。
出于特定场景的严格要求,必须使用Windows系统API ReadFile()完成操作。

for (iReadCounter = 0; iReadCounter < iReadCountLimit; iReadCounter++)
{
    readsize = DefineConstants.READ_BUF_SIZE;
    bool bResult = ReadFile(fhnd, readbuffer, (uint)readsize, out readresult, ref _overlapped);
    .
    .
}

核心诉求:实现指定ReadFile()从自定义的文件偏移/位置处开始读取数据。

可行实现方案

根据是否使用重叠IO(即代码中传入_overlapped参数的模式),有两种直接可用的实现方式:

方案1:重叠IO场景(适配当前代码写法)

当前代码调用ReadFile时传入了_overlapped结构,这种场景下不需要修改文件指针,直接给OVERLAPPED结构的偏移字段赋值即可指定读取起始位置:

  • Offset字段:填入目标偏移的低32位数值
  • OffsetHigh字段:填入目标偏移的高32位数值
  • 这里的偏移是从文件起始位置计算的字节偏移,和系统维护的默认文件指针位置无关,赋值完成后直接调用ReadFile就会从指定位置开始读取。

示例代码:

// 定义需要读取的起始偏移,例:从文件头开始4096字节位置
long customOffset = 4096;
// 给OVERLAPPED结构赋值偏移
_overlapped.Offset = (int)(customOffset & 0xFFFFFFFF);
_overlapped.OffsetHigh = (int)(customOffset >> 32);

// 正常调用ReadFile即可,会从customOffset位置开始读取
for (iReadCounter = 0; iReadCounter < iReadCountLimit; iReadCounter++)
{
    readsize = DefineConstants.READ_BUF_SIZE;
    bool bResult = ReadFile(fhnd, readbuffer, (uint)readsize, out readresult, ref _overlapped);
    // 后续处理逻辑
}

注意:这种方式指定偏移读取不会修改系统默认维护的文件指针位置,仅对当前传入OVERLAPPED的读操作生效。如果文件句柄是用FILE_FLAG_OVERLAPPED标志打开的,必须用这种方式指定偏移,调用移动文件指针的API不会对重叠IO读操作生效。

方案2:非重叠IO场景

如果调用ReadFile时最后一个lpOverlapped参数传入IntPtr.Zero(不使用重叠IO),可以在调用ReadFile前先移动文件指针到目标位置:

  • 优先调用SetFilePointerExAPI设置文件指针,该API原生支持64位偏移,处理大文件时不会出现精度问题,比旧版SetFilePointer更易用。
  • 移动文件指针时可以选择从文件头、当前位置、文件尾三个基准位置计算偏移,设置完成后调用ReadFile就会从新的指针位置开始读取,读取完成后指针会自动向后移动本次读取的字节长度。

示例逻辑:

// 定义需要读取的起始偏移,例:从文件头开始4096字节位置
long customOffset = 4096;
long newFilePointer;
// 从文件头开始计算,移动指针到目标偏移,0代表FILE_BEGIN即文件头基准
SetFilePointerEx(fhnd, customOffset, out newFilePointer, 0);
// 调用ReadFile,最后一个参数传空,不使用重叠IO
bool bResult = ReadFile(fhnd, readbuffer, (uint)readsize, out readresult, IntPtr.Zero);
注意事项
  • 指定偏移前需要校验偏移合法性,不要设置超过文件实际长度的偏移值,否则ReadFile会调用失败,返回的系统错误码会提示读取位置越界。
  • 两种方案不要混用:如果用重叠IO打开文件句柄,就必须通过OVERLAPPED结构指定偏移,不要额外调用文件指针移动API;如果用普通阻塞模式打开句柄,就通过移动文件指针的方式指定位置。

内容的提问来源于stack exchange,提问作者Hillel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:57:15