2017-02-27 11 views
1

異なるオフセットでファイルを同時に読み込もうとしています。私はposixシステムでpreadを使用してこれを行うことができますが、Windowsシステムの場合はReadFileを使用してそれを行う方法を理解できません。私は多くのWindowsのドキュメントを理解するのが難しいです。どのように私は代わりにReadFileを使用する必要がありますか?CコードでReadFileを使用する

編集作業コードhereを参照してください。

do { 
#ifdef _WIN32 
     OVERLAPPED overlapped; 
     memset(&overlapped, 0, sizeof(OVERLAPPED)); 

     overlapped.Offset = shard_meta->index*state->shard_size + total_read; 

     HANDLE file = (HANDLE)_get_osfhandle(fileno(state->original_file)); 
     SetLastError(0); 
     bool RF = ReadFile(file, read_data, AES_BLOCK_SIZE * 256, NULL, &overlapped); 
     if ((RF==0) && GetLastError() == ERROR_IO_PENDING) { 
      printf ("Asynch readfile started. I can do other operations now\n"); 
      while(!GetOverlappedResult(file, &overlapped, &read_bytes, TRUE)) { 
       if (GetLastError() == ERROR_IO_INCOMPLETE) { 
        printf("I/O pending: %d .\n",GetLastError()); 
       } else if (GetLastError() == ERROR_HANDLE_EOF) { 
        printf("End of file reached.\n"); 
        break; 
       } else { 
        printf("GetOverlappedResult failed with error:%d\n",GetLastError()); 
        break; 
       } 
      } 
     } else if ((RF == 0) && GetLastError() != ERROR_IO_PENDING) { 
      printf ("Error reading file :%d\n",GetLastError()); 
      goto clean_variables; 
     } 

#else 
     read_bytes = pread(fileno(state->original_file), 
         read_data, AES_BLOCK_SIZE * 256, 
         shard_meta->index*state->shard_size + total_read); 
#endif 
     total_read += read_bytes; 

     memset_zero(read_data, AES_BLOCK_SIZE * 256); 
    } while(total_read < state->shard_size && read_bytes > 0); 
+0

以下の作業のコードを参照してください。それは何を返すのですか?また、オフセット計算結果の下位32ビットにオフセットが完全に含まれることをお勧めします。 –

+0

読み込みを並行させるためには、ハンドルは 'FILE_FLAG_OVERLAPPED'で開かれていなければなりません。 –

+0

コードを更新しました@Andrew –

答えて

0

あなたは `のReadFile()`からの戻り値をチェックしていない

#ifdef _WIN32 
ssize_t pread(int fd, void *buf, size_t count, uint64_t offset) 
{ 
    long unsigned int read_bytes = 0; 

    OVERLAPPED overlapped; 
    memset(&overlapped, 0, sizeof(OVERLAPPED)); 

    overlapped.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 32); 
    overlapped.Offset = (uint32_t)(offset & 0xFFFFFFFFLL); 

    HANDLE file = (HANDLE)_get_osfhandle(fd); 
    SetLastError(0); 
    bool RF = ReadFile(file, buf, count, &read_bytes, &overlapped); 

    // For some reason it errors when it hits end of file so we don't want to check that 
    if ((RF == 0) && GetLastError() != ERROR_HANDLE_EOF) { 
     errno = GetLastError(); 
     // printf ("Error reading file : %d\n", GetLastError()); 
     return -1; 
    } 

    return read_bytes; 
} 

ssize_t pwrite(int fd, const void *buf, size_t count, uint64_t offset) 
{ 
    long unsigned int written_bytes = 0; 

    OVERLAPPED overlapped; 
    memset(&overlapped, 0, sizeof(OVERLAPPED)); 

    overlapped.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 32); 
    overlapped.Offset = (uint32_t)(offset & 0xFFFFFFFFLL); 

    HANDLE file = (HANDLE)_get_osfhandle(fd); 
    SetLastError(0); 
    bool RF = WriteFile(file, buf, count, &written_bytes, &overlapped); 
    if ((RF == 0)) { 
     errno = GetLastError(); 
     // printf ("Error reading file :%d\n", GetLastError()); 
     return -1; 
    } 

    return written_bytes; 
} 
#endif 
+0

ドキュメントから: "hFileがFILE_FLAG_OVERLAPPED [...]で開かれた場合、lpNumberOfBytesReadパラメータはNULLに設定する必要があります。GetOverlappedResult関数を使用して実際の読み込みバイト数を取得してください。 –

関連する問題