3

プログラム全体に、特定のファイルにデータを追加する必要がある関数が複数あるとします。プログラムの開始時にグローバル ファイル ハンドルを使用してファイルを開き、必要な場所に追加できるようにします。(ファイルハンドルを引数として関数に渡すことができることはわかっていますが、それはこの質問の目的ではありません)。プログラムの最初にファイルハンドルを開き、最後に閉じるのは悪いことですか? それとも、関数に言ってvoid AppendFile(char *data_to_append);からファイルを開いて追加し、この同じ関数で閉じる方が良いですか? プログラムが停止した場合、FD がまだ使用されていることが唯一の悪いことですが、同時に、関数を使用すると、同じファイルを何百回も何百回も開いたり閉じたりすることになります。

4

7 に答える 7

2

おそらく、1 回のオープンと 1 回のクローズを行うのが最善です。ノンストップで開閉すると、大量の無駄な IO が発生します。

一度に 1 つのスレッドだけがファイル ハンドルに書き込むことができるように、mutex を使用してこの関数を保護することをお勧めします。

ただし、最終的には必ずファイルを閉じてください。

于 2010-09-15T17:59:29.163 に答える
1

グローバル変数は通常、良いことではありません。ただし、小さなプログラムの場合は問題ありません。

グローバル ファイル ハンドルを引き続き使用している間は、コード全体に分散させるのではなく、グローバル ファイルvoid AppendFile(char *data_to_append);のみを参照する関数を介してのみアクセスすることを検討してください。AppendFile

ファイルが頻繁にアクセスされる場合、アクセスのたびにファイルを開いたり閉じたりすると、膨大な量になる可能性があります。

また、ファイル ハンドルは通常、プログラムが終了する (終了するか、正常に終了する) ときに閉じられるため、プログラムがクラッシュしても何もリークしません。

于 2010-09-15T18:32:11.520 に答える
1

プログラムがシングル スレッドであれば問題ありません。ファイル ハンドルが開いている間に終了した場合は、とにかくオペレーティング システムによって閉じられる可能性があります。そうでない場合、 AppendFile 関数内で死なないことを保証するものは何ですか?

ただし、その AppendFile 関数を作成することをお勧めします。これにより、書き込みプロセスが簡素化され、ファイル ハンドルに関する変更が、多数の fwrite() を散りばめた場合よりも簡単に変更できるようになります。

于 2010-09-15T18:00:22.297 に答える
1

ファイルがゴミ箱に入れられたり、データが失われたりしないように、どれだけ気にするかによって異なります。プログラムがクラッシュした場合、まだ完了していない (完了しただけでなく、フラッシュされてディスクにコミットされた) すべての書き込みがどうなるかについての保証はありません。コミットされていない書き込みがある場合、それらは破棄されるか、中途半端になる可能性があります。ファイルを閉じると、これらの書き込みがコミットされることが保証されます。

書き込みが頻繁に行われない場合は、open/append/close の方が良い考えです。IMO ですがAppendFile、既に開いているファイル ハンドルで動作するようにすることもできるため、実際にはどちらの方法でもうまく動作します。

それに加えて、スレッドをまったく使用する場合、ファイルへのランダムな書き込みは必要ありません。それらを同期する何らかの方法が必要です。または同様の関数をAppendFile使用すると、その同期ポイントが得られます。そこにコードを追加して、別のスレッドが終了するまで待機できます。100 の異なる場所にあるファイルに直接書き込んでいるときに、それを試してみてください。

于 2010-09-15T18:01:31.717 に答える
1

データベースがテキスト ファイルの非常に優れた代替手段となる場合があります。特に、データベースがそもそもテキスト ファイルを置き換えるように特別に設計されている場合は特にそうです :)

SQLite ( http://www.sqlite.org/ ) を見てください。

SQLite は Oracle の代わりではなく、fopen() の代わりと考えてください。

于 2010-09-15T18:24:06.987 に答える
0

はい。

最も役立つ答えではありませんが、あなたの質問が一般的で漠然としていて、詳細を提供できないことを残念に思います。この FD へのアクセスがプログラム全体に散らばっている場合は、高レベルの設計に何か問題があることを示唆しています。これらの個別のアクセスは何らかの形で相互に関連していますか? ファイルにアクセスする少数のポイントに結合できますか? あなたのプログラムには、クラスでより適切に実装される何らかの暗黙のデータ構造がありますか?

于 2010-09-15T17:59:56.307 に答える
0

ファイル ハンドルを意味する場合FILE *、多くのユーザーが最初に開いて最後に閉じることは、POSIX システムで単一の stdio 関数呼び出しで書き込みを行う限り、複数のスレッドが存在する場合でも期待どおりに動作するはずです。

ファイル ハンドルとは、オペレーティング システムの open 呼び出しによって返される整数を意味する場合、writeオペレーティング システムは、そのファイルに関連付けられたバッファーにデータを転送している間、ファイルをロックするため、(または同様の) への 1 回の呼び出し内で通常はスレッド セーフです。

プログラムがシングル スレッド アプリケーションである場合は、どちらの方法についてもあまり心配する必要はありません。

ファイルを繰り返し開いたり、追加したり、閉じFILE *たりすると、複数のスレッドで stdio を使用する場合、または異なるs がアプリケーション内でバッファを共有しないAppendFileため、何らかの方法で への呼び出しが再帰的に行われた場合に問題が発生する可能性があります。FILE *あるスレッドで変更された場合、他のスレッドがそれらの変更を上書きする可能性があります。

同様のことが os ファイル ハンドル (open によって返される整数) でも発生する可能性があります。これは、異なる呼び出しがopen異なるファイル ハンドルを生成し、それらのシーク位置が共有されないためです。O_APPENDOSがこれを処理する追加専用モード( )でファイルを開くことができない限り、実際にはファイルの最後にはありません。

いずれにせよ、ファイルを何度も開いたり閉じたりすると、多くの余分な作業が発生します。

于 2010-09-15T18:26:31.667 に答える