質問

私のC++アプリケーションでは、ISOファイルを非同期で読み取ろうとしています。 createfile - 重なったフラグとそれ以降 - readfile。ただし、このコードを単純なファイル(たとえばtxtファイル)で試してみると、機能します。しかし、このコードをisoファイルで実行すると失敗します。MSDN で、圧縮ファイルは readfile sync 呼び出しでのみ読み取ることができると見ました。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");
            }

        }

   }

ありがとう

役に立ちましたか?

解決

に使用している値を投稿していません BUF_SIZE 定数ですが、ボリューム セクター サイズの整数倍であることを確認してください。これは、バッファリングされていないファイル ストリームを使用する場合によくある落とし穴です。のドキュメント FILE_FLAG_NO_BUFFERING の中に CreateFile() ドキュメンテーション 言います:

FILE_FLAG_NO_BUFFERING フラグを使用して CreateFile で開かれたファイルを正常に操作するには、厳格な要件があります。詳細については、を参照してください。 ファイルバッファリング.

ファイルバッファリングのメモに関するページ:

前述のように、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 構造。あなたは設定しません Internal そして InternalHigh メンバーは0に。必ずクリアしてください OVERLAPPED 次のように構造化します。

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

次に、ファイル オフセットとイベント ハンドルを設定できます。

編集:に関する次の注意事項も考慮してください。 lpNumberOfBytesRead パラメータを ReadFile():

これが非同期操作である場合、潜在的に誤った結果を避けるために、このパラメーターには NULL を使用してください。[...] 詳細については、「備考」セクションを参照してください。

他のヒント

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

エラーがない場合でも、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
それが役立つことを願っています。このトピックについて多くを見つけることができません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top