首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >异步读文件- iso文件c++

异步读文件- iso文件c++
EN

Stack Overflow用户
提问于 2012-02-21 15:18:21
回答 2查看 7.9K关注 0票数 1

在我的c++应用程序中,我尝试通过createfile异步读取iso文件-带有重叠标志,然后是readfile。但是,当我在一个简单的文件(例如txt文件)上尝试这段代码时,它可以工作。但是当我在iso文件上运行这段代码时-它失败了。我在MSDN中看到压缩文件只能通过readfile sync调用读取。iso文件是否在此类别中?如果是-你有其他建议如何异步读取iso文件吗?

这是我的代码:

代码语言:javascript
复制
int _tmain(int argc, _TCHAR* argv[])
{


HANDLE hFile;
    DWORD NumberOfBytesRead = 0, dw;
    BYTE *buf = (BYTE*)malloc(BUF_SIZE*sizeof(BYTE));
    OVERLAPPED overlapped;
    overlapped.Offset = overlapped.OffsetHigh = 0;  
    memset(buf, 0, 1024);

overlapped.hEvent = CreateEvent(NULL, true, false, NULL); 
if(NULL == overlapped.hEvent)
    printf("error");

hFile = CreateFile("xxx.iso",
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING , 
                  NULL);



if (hFile == INVALID_HANDLE_VALUE)
        printf("invalid hfile\n");

   int i;   
   i= ReadFile(hFile,
                 buf,
                 BUF_SIZE,
                 &NumberOfBytesRead,
        &overlapped);
   if( GetLastError() == ERROR_IO_PENDING)
   {


       dw = WaitForSingleObject(overlapped.hEvent, INFINITE);
    if(dw ==  WAIT_OBJECT_0)
        if (GetOverlappedResult(hFile,&overlapped,&NumberOfBytesRead, TRUE) != 0)   
        {
            if (NumberOfBytesRead != 0) 
            {
                printf("!!!\n");
            }

        }

   }

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-21 16:30:02

您还没有发布用于BUF_SIZE常量的值,但请确保它是卷扇区大小的整数倍。这是使用无缓冲文件流时的常见陷阱。CreateFile() documentation中的FILE_FLAG_NO_BUFFERING文档中这样写道:

使用FILE_FLAG_NO_BUFFERING标志成功处理使用CreateFile打开的文件有严格的要求,有关详细信息,请参阅File Buffering

关于文件缓冲注释的页面:

如前所述,当使用FILE_FLAG_NO_BUFFERING打开的文件时,应用程序必须满足某些要求。以下详细说明适用:

  • 文件访问大小(包括重叠结构中的可选文件偏移量)的字节数必须是卷扇区大小的整数倍。例如,如果扇区大小为512字节,则应用程序可以请求512、1,024、1,536或2,048字节的读取和写入,但不能请求335、981或7,171字节的读取和写入。用于读取和写入操作的
  • 文件访问缓冲区地址应与物理扇区对齐,这意味着在内存中的地址是卷物理扇区大小的整数倍。根据磁盘的不同,可能不会强制执行此要求。

应用程序开发人员应注意市场上正在推出的物理介质扇区大小为4,096字节的新型存储设备。

在我的系统上,这个值是4K,一次读取任何小于4K的值都会产生错误。在Microsoft的许多代码示例中,1K是默认的缓冲区大小,因此改编示例通常会导致未缓冲的I/O出现错误。

编辑:还要确保将OVERLAPPED结构的所有成员清零。不要将InternalInternalHigh成员设置为0。始终按照以下方式清除OVERLAPPED结构:

代码语言:javascript
复制
OVERLAPPED overlapped;
ZeroMemory(&overlapped, sizeof(OVERLAPPED));

然后,您可以设置文件偏移量和事件句柄。

编辑:还要考虑以下有关ReadFile()lpNumberOfBytesRead参数的注意事项

如果这是一个异步操作,则对此参数使用NULL,以避免潜在的错误结果。..。有关更多信息,请参阅备注部分。

票数 2
EN

Stack Overflow用户

发布于 2012-10-11 01:46:17

我建议仔细注意重叠的OffsetOffsetHigh字段,特别是在读取一个大小超过32位无符号整数边界的文件时。我相信你面临的问题潜伏在那里。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9373632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档