3

バイナリ ファイルに数回アクセスしているコードがあります。関数を呼び出すたびに、読み取り用にファイルが開かれ、必要なバイト数 (n毎回バイトなど) だけが読み取られます。

バイナリファイルには時系列データが含まれています。私ができるようにしたいのは、関数呼び出しをループで実行することです。関数を呼び出して同じファイルを開くたびに、次のチャンクを読み取る必要があります。つまり、毎回ファイル ポインタをリセットする必要はありません。これを行う方法はありますか?

関数は次のようになります。

int readBinary(float *binImage, int gelements) {
    imageFile = fopen("tmpImageFile", "r");
    if (imageFile == NULL) {
       fprintf(stderr, "Error opening file\n");
       return (1);
    }
    fread(binImage, sizeof(float), gelements, imageFile);
    return 0;
}

私のメイン コードでは、毎回binImageサイズの配列を与えて、ループを実行したいと思います。それが避けられる場合gelementsは、サイズの配列を指定したくありません。gelements * nLoop

4

4 に答える 4

6

ファイルポインタを保持するように静的変数を使用します。

int readBinary(float *binImage, int gelements) {
    static FILE *imageFile = NULL;
    if (imageFile == NULL) {
       imageFile = fopen("tmpImageFile", "r");
       if (imageFile == NULL) {
          perror("Error opening file: ");
          return (1);
       }
    }
    fread(binImage, sizeof(float), gelements, imageFile);
    return 0;
}
于 2013-04-20T18:29:11.373 に答える
6

簡単な経験則は次のとおりです。

機能間の責任を適切に分離すると、生活が楽になります

静的変数やグローバル変数を使用すると、生活が複雑になります」。

この場合、データreadBinaryの管理と読み取りの両方の責任を関数に与えるのFILEは多すぎます。

関数はハンドルを閉じないことに注意してください。

ハンドルが関数内のローカル スタティックである場合、それを閉じることはできません。また、関数が「tmpImageFile」のみを使用するように永久にロックされることも意味します (これは、関数の署名または欠落しているドキュメントからすぐにはわかりません)。

ハンドルがグローバルの場合、時期尚早に閉じる可能性があります。

「ファイルを開く」という責任を取り除くと、readBinary関数は単なる呼び出しになることに注意してくださいfread

readBinaryこれを処理する最善の方法は、関数を完全にスキップすることです。

ループでデータを読み取る呼び出し元があるとします。この呼び出し元に を開く責任を持たせ、ループ内で直接FILE使用freadし、完了したらファイルを閉じます。

さて、これは呼び出し元に過度の責任を与える可能性があります。呼び出し元に をパラメーターとして受け入れさせFILE*、ファイル管理の責任を呼び出し元に与えるだけです。または、ファイルの有効期間を管理することが理にかなっている場所に応じて、呼び出し元の呼び出し元の呼び出し元。

于 2013-04-20T19:07:02.127 に答える
3

FILE*as パラメータを関数に渡します。

int readBinary(float *binImage, int gelements, FILE *imageFile) {
    int bytes = fread(binImage, sizeof(float), gelements, imageFile);
    return bytes != -1 ? 0 : 1;
}

また、戻り値の簡単なチェックを追加freadし、戻り値の規則に変換しました。この関数は非常に単純に見えますがfread、エラー出力のようなものを追加したくない場合を除き、直接呼び出すことができます。

于 2013-04-20T18:38:51.350 に答える