2

それぞれ 195 個の double を持つ 30e6 の位置で構成される大きなバイナリ ファイルを読み込もうとしています。ファイルが大きすぎてすべてをメモリに読み込めないため、10000 ポジションのチャンクで読み込んでいます。次に、それを使用していくつかの計算を行い、次のチャンクを読み取ります....

ファイルへのランダム アクセスが必要なので、ファイルから特定のチャンク (unsigned int チャンク) を読み取り、それを **chunk_data に格納する関数を作成しました。この関数は、読み取った位置の総数を返します。

unsigned int read_chunk(double **chunk_data, unsigned int chunk) {
    FILE *in_glf_fh;
    unsigned int total_bytes_read = 0;

    // Define chunk start and end positions
    unsigned int start_pos = chunk * 10000;
    unsigned int end_pos = start_pos + 10000 - 1;
    unsigned int chunk_size = end_pos - start_pos + 1;

    // Open input file
    in_glf_fh = fopen(in_glf, "rb");
    if( in_glf_fh == NULL )
        error("ERROR: cannot open file!");

    // Search start position
    if( fseek(in_glf_fh, start_pos * 195 * sizeof(double), SEEK_SET) != 0 )
        error("ERROR: cannot seek file!");

    // Read data from file
    for(unsigned int c = 0; c < chunk_size; c++) {
         unsigned int bytes_read = fread ( (void*) chunk_data[c], sizeof(double), 195, in_glf_fh);
         if( bytes_read != 195 && !feof(in_glf_fh) )
             error("ERROR: cannot read file!");
         total_bytes_read += bytes_read;
    }

    fclose(in_glf_fh);
    return( total_bytes_read/195 );
}

問題は、いくつかのチャンクを読み取った後fread()、間違った値を与え始めることです! また、チャンクサイズに応じて、fread()おかしな動作を開始する位置が異なります。

chunk of 1 pos, wrong at chunk 22025475
chunk of 10000 pos, wrong at chunk 2203
chunk of 100000 pos, wrong at chunk 221

何が起こっているのか誰にも分かりますか?

4

1 に答える 1

4

30e6 positionsそれが16進数ではなく、代わりに30,000,000であると判断した後、次の問題を検討しfseek()てください。ファイルに46,800,000,000バイトがあります。プレーンバニラfseek()(16ビットおよび32ビットプラットフォーム)は、最初の2 ^ 32-1バイト(= 4,294,967,295)に制限されています。

プログラムが実行されているプラ​​ットフォームによっては、lseek64またはそれに相当するものを使用する必要がある場合があります。Linuxでは、

  • で使用lseek()する

    #define _FILE_OFFSET_BITS 64

  • llseek()

  • lseek64()

于 2012-10-15T18:32:10.863 に答える