Readfile async - iso files c ++

时间:2012-02-21 07:18:21

标签: c++ winapi asynchronous readfile createfile

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

这是我的代码:

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");
            }

        }

   }

感谢

3 个答案:

答案 0 :(得分:2)

您尚未发布BUF_SIZE常量所使用的值,但请确保它是卷扇区大小的整数倍。这是使用无缓冲文件流时常见的陷阱。 CreateFile() documentationFILE_FLAG_NO_BUFFERING的文档说:

  

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

文件缓冲记录页面:

  

如前所述,应用程序在工作时必须满足某些要求   使用FILE_FLAG_NO_BUFFERING打开文件。以下具体内容适用:

     
      
  • 文件访问大小,包括OVERLAPPED结构中的可选文件偏移量,如果   指定的,必须是一个字节,它是卷扇区的整数倍   尺寸。例如,如果扇区大小为512字节,则应用程序可以请求读取和   写入512,1024,1,536或2,048字节,但不包括335,981或7,171字节。

  •   
  • 读写操作的文件访问缓冲区地址应为物理扇区   对齐,这意味着在内存中的地址上对齐,这是地址的整数倍   卷的物理扇区大小。根据磁盘,此要求可能不是   执行。

  •   
     

应用程序开发人员应注意新的存储设备类型   以物理媒体扇区大小4,096字节进入市场。

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

修改:还要确保将OVERLAPPED结构的所有成员清零。您未将InternalInternalHigh成员设置为0.始终按以下方式清除OVERLAPPED结构:

OVERLAPPED overlapped;
ZeroMemory(&overlapped, sizeof(OVERLAPPED));

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

修改:还要考虑以下有关ReadFile()lpNumberOfBytesRead参数的说明:

  

如果这是一个异步操作以避免可能的错误结果,请对此参数使用NULL。 [...]有关详细信息,请参阅备注部分。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

如果你像Dodo所说的那样调用GetLastError(),即使没有错误也会更好。 ReadFile返回的内容将会非常有用。就ISO文件而言,我认为它们是压缩文件类型。您可以查找使用LzRead函数。在这里看看:“

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
”。您也可以使用LzOpenFile打开该文件。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365225%28v=vs.85%29.aspx
希望它有所帮助。不能在这个主题上找到很多。