1

私のc++アプリケーションでは、isoファイルを非同期で読み取ります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");
            }

        }

   }

ありがとう

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

特に32ビットの符号なし整数の境界を超えるサイズのファイルを読み取る場合は、オーバーラップするフィールドOffsetとフィールドに注意を払うことをお勧めします。OffsetHighあなたが直面している問題はそこに潜んでいると思います。

于 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 に答える