web-dev-qa-db-ja.com

ファイル記述子とファイルポインターの違いは何ですか?

ファイル記述子とファイルポインターの違いを知りたい。

また、他のシナリオではなく、どちらのシナリオで使用しますか?

103
karthi_ms

ファイル記述子は、Linuxや他のUnixライクなシステムで、カーネルレベルで開かれたファイル(またはソケットなど)を識別するために使用される低レベルの整数「ハンドル」です。

read()write()など、実際のUnix呼び出しに「裸の」ファイル記述子を渡します。

FILEポインターは、ファイルを表すために使用されるC標準ライブラリレベルの構造です。 FILEはファイル記述子をラップし、I/Oを簡単にするためにバッファリングおよびその他の機能を追加します。

FILEポインターを、fread()fwrite()などの標準C関数に渡します。

133
unwind

1つはバッファリング(_FILE *_)され、もう1つはバッファリングされません。実際には、何をしているのかわからない場合や、ファイルが実際にソケットなどである場合を除き、「実際の」ファイル(つまり、ドライブ)から読み取る場合、ほとんど常に_FILE *_を使用します。 。

fileno()を使用して_FILE *_からファイル記述子を取得でき、fdopen()を使用してファイル記述子からバッファリングされた_FILE *_を開くことができます。

56
Ben

ファイル記述子は、Posixのopen() callから取得する単なる整数です。標準のC fopen()を使用すると、FILE構造体が返されます。 FILE構造体には、ファイルの終わりやエラーインジケータ、ストリームの位置など、このファイル記述子が含まれます。

したがって、fopen()を使用すると、open()と比較してある程度の抽象化が得られます。一般的にfopen()を使用する必要があります。これはより移植性があり、FILE構造体を使用する他のすべての標準C関数、つまりfprintf()およびファミリを使用できるためです。

どちらかを使用してもパフォーマンスの問題はありません。

18
Martin Wickman

ファイル記述子とファイルポインタ

ファイル記述子:

ファイル記述子は、open()システムコールによって返される整数値です。

int fd = open (filePath, mode);

  1. 低/カーネルレベルハンドラー。
  2. uNIXシステムコールのread()およびwrite()に渡します。
  3. バッファリングなどの機能は含まれません。
  4. 移植性が低く、効率が悪い。

ファイルポインター:

ファイルポインターは、fopen()ライブラリー関数によって返されるC構造体へのポインターです。これは、ファイルの識別、ファイル記述子のラッピング、バッファリング機能、および必要な他のすべての機能に使用されますI/O操作の場合。ファイルポインタのタイプは[〜#〜] file [〜#〜]で、その定義は/にあります。"/ usr/include/stdio.h"。この定義は、コンパイラごとに異なる場合があります。

FILE *fp = fopen (filePath, mode);

// A FILE Structure returned by fopen 
    typedef struct 
    {
        unsigned char   *_ptr;
        int     _cnt;
        unsigned char   *_base;
        unsigned char   *_bufendp;
        short   _flag;
        short   _file;
        int     __stdioid;
        char    *__newbase;
#ifdef _THREAD_SAFE
        void *_lock;
#else
        long    _unused[1];
#endif
#ifdef __64BIT__
        long    _unused1[4];
#endif /* __64BIT__ */
    } FILE;
  1. 高レベルのインターフェースです。
  2. Fread()およびfwrite()関数に渡されます。
  3. バッファリング、エラー表示、およびEOF検出など。
  4. より高い移植性と効率性を提供します。
13
Yogeesh H T

役に立つかもしれないポイントを追加したい。

FILE *について

  1. プロセス間通信(IPC)には使用できません。
  2. 一般的な目的のバッファI/Oが必要な場合に使用します(printf、frpintf、snprintf、scanf)
  3. デバッグログに何度も使用しています。例、

                 FILE *fp;
                 fp = fopen("debug.txt","a");
                 fprintf(fp,"I have reached till this point");
                 fclose(fp);
    

FILE DESCRIPTORについて

  1. 通常、IPCに使用されます。

  2. * nixシステム上のファイル(デバイス、ファイル、ソケットなど)に低レベルの制御を与えるため、FILE *よりも強力です。

12
Akshay Patil

ディスカッションを終了するためのメモ(興味がある場合)....

fopenは安全でない可能性があります。おそらく、_fopen_s_またはopenを排他的なビットを設定して使用する必要があります。 C1Xはxモードを提供しているため、_"rx"_、_"wx"_などのモードでfopenを使用できます。

openを使用する場合、open(..., O_EXCL | O_RDONLY,... )またはopen(..., O_CREAT | O_EXCL | O_WRONLY,... )を検討できます。

たとえば、 fopen()およびファイル作成に関して仮定しないでください を参照してください。

3
jww

FILE *は、sprintf()sscanf()fgets()feof()など。

ファイル記述子APIは低レベルであるため、ソケット、パイプ、メモリマップファイル(および通常のファイル)を操作できます。

3
qrdl

システムコールは、主にreadwriteなどのファイル記述子を使用します。ライブラリ関数は、ファイルポインター(printfscanf)を使用します。ただし、ライブラリ関数は内部的にシステムコールのみを使用しています。

1
Pavunkumar