1

在我的 c++ 应用程序中,我很想通过createfile- 使用重叠标志并在它之后 -异步读取 iso 文件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");
            }

        }

   }

谢谢

4

3 回答 3

2

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

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

文件缓冲说明页面:

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

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

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

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

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

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

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

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

编辑:还考虑以下关于lpNumberOfBytesRead参数的注释ReadFile()

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

于 2012-02-21T08:30:01.700 回答
1

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

于 2012-10-10T17:46:17.333 回答
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
希望它会有所帮助。在这个话题上找不到太多。

于 2012-02-21T08:13:41.350 回答