web-dev-qa-db-ja.com

C fopen vs open

使用したい理由はありますか(構文上の理由以外)

FILE *fdopen(int fd, const char *mode);

または

FILE *fopen(const char *path, const char *mode);

の代わりに

int open(const char *pathname, int flags, mode_t mode);

linux環境でCを使用する場合

190
LJM

最初に、fdopenがオプションであり、fopenが他の可能な選択である場合、openを使用する特に適切な理由はありません。 FILE *が必要な場合、最初にopenを使用してファイルを開くべきではありません。そのため、そのリストにfdopenを含めることは、他のものとあまり似ていないため、不正確でわかりにくいものです。ここで重要な違いは、C標準のFILE *とOS固有のファイル記述子であるため、これを無視します。

fopenの代わりにopenを使用する主な理由は4つあります。

  1. fopenは、バッファリングIOを提供します。__<< IO>] _は、openを使用した場合よりもはるかに高速になることがあります。
  2. fopenは、ファイルがバイナリモードで開かれていない場合に行末変換を行います。これは、プログラムが非Unix環境に移植されている場合に非常に役立ちます。
  3. FILE *を使用すると、fscanfおよびその他のstdio関数を使用できます。
  4. ANSI Cのみをサポートし、open関数をサポートしない他のプラットフォームにコードを移植する必要があるかもしれません。

私の意見では、翻訳を終了する行はあなたを助けるよりもあなたの邪魔になることが多く、fscanfの解析は非常に弱く、必然的にあなたはそれを捨ててより有用なものを支持することになります。

また、Cをサポートするほとんどのプラットフォームにはopen関数があります。

それはバッファリングの質問を残します。主にファイルを順番に読み書きする場所では、バッファリングのサポートが非常に役立ち、速度が大幅に向上します。しかし、データがファイルにあると予想されるときにデータがファイルに収まらないという興味深い問題につながる可能性があります。適切なタイミングでfcloseまたはfflushを覚えておく必要があります。

シーク(別名fsetposまたはfseekを使用している場合、2番目は標準に準拠した方法で使用するのが少し難しい)の場合、バッファリングの有用性はすぐに低下します。

もちろん、私の偏見は、私はソケットをたくさん使う傾向があることであり、あなたは本当に非ブロッキングIO(これはFILE *が合理的な方法で完全にサポートできない)バッファリングがまったくなく、多くの場合、複雑な解析要件があり、実際に私の認識を色付けします。

221
Omnifarious

open() は低レベルのOS呼び出しです。 fdopen() は、osレベルのファイル記述子をC言語のより高いレベルのFILE抽象化に変換します。 fopen() バックグラウンドでopen()を呼び出し、FILEポインターを直接提供します。

生のファイル記述子ではなくFILEオブジェクトを使用することにはいくつかの利点があります。これには、使いやすさだけでなく、組み込みのバッファリングなどの他の技術的な利点も含まれます。特に、バッファリングは一般に、かなりのパフォーマンス上の利点をもたらします。

46
Emil H

Cでfopen vs open

1)fopenライブラリ関数で、openシステムコールです。

2)fopenbuffered IOを提供します。これはnon bufferedであるopenと比較して高速です。

3)fopenportableですが、openportableopenは環境固有)です。

4)fopenは、FILE構造体(FILE *)へのポインターを返します。 openは、ファイルを識別する整数を返します。

5)FILE *を使用すると、fscanfおよびその他のstdio関数を使用できます。

26
Yogeesh H T

FILE *がある場合は、fscanffprintffgetsなどの関数を使用できます。ファイル記述子だけがある場合は、入力および出力ルーチンreadwriteなどを制限します(ただし、高速になる可能性があります)。

11
dreamlax

openを使用することが実際のパフォーマンス上の利点であるアプリケーションの0.1%の一部でない限り、fopenを使用しない正当な理由はありません。 fdopenに関する限り、ファイル記述子で遊んでいないのであれば、その呼び出しは必要ありません。

fopenとそのメソッドファミリ(fwritefreadfprintfなど)を使用すると、非常に満足します。同様に重要なことは、他のプログラマーがあなたのコードに満足することです。

10
user7116

オープン、読み取り、書き込みを使用すると、信号の相互作用を心配する必要があります。

呼び出しがシグナルハンドラによって中断された場合、関数は-1を返し、errnoをEINTRに設定します。

したがって、ファイルを閉じる適切な方法は

while (retval = close(fd), retval == -1 && ernno == EINTR) ;
7
digy

open()は、各fopen()ファミリ関数の最後に呼び出されます。 open()はシステムコールであり、fopen()はユーザーが使いやすいようにラッパー関数としてライブラリによって提供されます

4
theadnangondal

open()はシステムコールであり、Unixベースのシステムに固有であり、ファイル記述子を返します。別のシステムコールであるwrite()を使用して、ファイル記述子に書き込むことができます。
fopen()は、ファイルポインターを返すANSI C関数呼び出しであり、他のOSに移植可能です。 fprintfを使用して、ファイルポインターに書き込むことができます。

Unixの場合:
次を使用して、ファイル記述子からファイルポインターを取得できます。

fP = fdopen(fD, "a");

次を使用して、ファイルポインターからファイル記述子を取得できます。

fD = fileno (fP);
4
Arun Chettoor

開くために必要なフラグにも依存します。書き込みおよび読み取り(および移植性)の使用に関しては、上記のようにf *を使用する必要があります。

ただし、基本的に標準フラグ(rwやappendフラグなど)以外を指定する場合は、プラットフォーム固有のAPI(POSIX openなど)またはこれらの詳細を抽象化するライブラリを使用する必要があります。 C標準には、このようなフラグはありません。

たとえば、ファイルが存在する場合にのみ、ファイルを開くことができます。作成フラグを指定しない場合、ファイルが存在する必要があります。作成する排他を追加すると、ファイルが存在しない場合にのみファイルが作成されます。他にもたくさんあります。

たとえば、Linuxシステムでは、sysfsを通じて公開されるLEDインターフェイスがあります。ファイルを介してledの明るさを公開します。 0〜255の範囲の文字列としての数値の書き込みまたは読み取り。もちろん、そのファイルを作成したくないので、存在する場合にのみ書き込みます。クールなこと:fdopenを使用して、標準呼び出しを使用してこのファイルを読み書きします。

2
Ritualmaster

アプリケーションのfopen()からopen()に変更しました。fopenfgetcを実行するたびにfopenが二重読み取りを引き起こしたためです。二重読み取りは、私が達成しようとしていたことを破壊するものでした。 open()はあなたが求めていることをしているようです。

1
Ersatz Splatt