В чем разница между дескриптором файла и указателем файла? - PullRequest
99 голосов
/ 11 марта 2010

Я хочу знать разницу между дескриптором файла и указателем файла.

Кроме того, в каком сценарии вы бы использовали один вместо другого?

Ответы [ 8 ]

130 голосов
/ 11 марта 2010

Файловый дескриптор - это низкоуровневый целочисленный «дескриптор», используемый для идентификации открытого файла (или сокета, или чего-либо еще) на уровне ядра в Linux и других Unix-подобных системах.

Вы передаете «голые» файловые дескрипторы реальным вызовам Unix, таким как <a href="http://linux.die.net/man/2/read" rel="noreferrer">read()</a>, <a href="http://linux.die.net/man/2/write" rel="noreferrer">write()</a> и т. Д.

Указатель FILE - это стандартная конструкция уровня библиотеки C, используемая для представления файла. FILE оборачивает дескриптор файла и добавляет буферизацию и другие функции, облегчающие ввод / вывод.

Вы передаете FILE указатели на стандартные функции C, такие как <a href="http://linux.die.net/man/3/fread" rel="noreferrer">fread()</a> и <a href="http://linux.die.net/man/3/fwrite" rel="noreferrer">fwrite()</a>.

55 голосов
/ 11 марта 2010

Один буферизован (FILE *), а другой нет. На практике вы хотите использовать FILE * почти всегда, когда вы читаете из «реального» файла (т.е. на диске), если вы не знаете, что делаете, или если ваш файл на самом деле является сокетом или около того .. 1003 *

Вы можете получить дескриптор файла из FILE *, используя fileno(), и вы можете открыть буфер FILE * из дескриптора файла, используя fdopen()

17 голосов
/ 11 марта 2010

Файловый дескриптор - это просто целое число, которое вы получаете из вызова Posix 'open(). Используя стандарт C fopen(), вы получаете FILE структуру обратно. Структура FILE содержит дескриптор этого файла среди других вещей, таких как конец файла и индикатор ошибки, позиция потока и т. Д.

Таким образом, использование fopen() дает вам определенное количество абстракции по сравнению с open(). В общем случае вы должны использовать fopen(), поскольку он более переносим, ​​и вы можете использовать все другие стандартные функции C, которые используют структуру FILE, то есть fprintf() и семейство.

Нет проблем с производительностью при использовании или.

12 голосов
/ 11 декабря 2015

Дескриптор файла и указатель файла

Дескриптор файла:

Дескриптор файла является целочисленным значением, возвращаемым системным вызовом open().

int fd = open (filePath, mode);

  1. Низкий / Уровень ядра обработчик.
  2. переход к read () и write () системных вызовов UNIX.
  3. Не включает буферизацию и такие функции.
  4. Менее портативен и неэффективен.

Указатель файла:

File Pointer - указатель на структуру C, возвращаемую библиотечной функцией fopen(), которая используется для идентификации файла, обертывания файлового дескриптора, буферизации и всех других функций, необходимых для операции ввода-вывода . Указатель файла имеет тип 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. Обеспечивает более высокую мобильность и эффективность.
11 голосов
/ 10 февраля 2013

Хотите добавить очки, которые могут быть полезны.

О FILE *

  1. нельзя использовать для межпроцессного взаимодействия (IPC).
  2. используйте его, когда вам необходим общий буферизованный ввод / вывод (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 *.

3 голосов
/ 11 марта 2010

FILE * более полезен при работе с текстовыми файлами и пользовательским вводом / выводом, поскольку позволяет использовать функции API, такие как sprintf(), sscanf(), fgets(), feof() и т. Д.

API дескриптора файла является низкоуровневым, поэтому он позволяет работать с сокетами, каналами, отображенными в память файлами (и обычными файлами, конечно).

2 голосов
/ 12 февраля 2013

Просто записка, чтобы закончить обсуждение (если интересно) ....

fopen может быть небезопасным, и вам, вероятно, следует использовать fopen_s или open с установленными эксклюзивными битами. C1X предлагает x режимы, так что вы можете fopen с режимами "rx", "wx" и т. Д.

Если вы используете open, вы можете рассмотреть open(..., O_EXCL | O_RDONLY,... ) или open(..., O_CREAT | O_EXCL | O_WRONLY,... ).

См., Например, Не делайте предположений о fopen () и создании файла .

1 голос
/ 11 марта 2010

Системные вызовы в основном используют дескриптор файла, например read и write. Функция библиотеки будет использовать файловые указатели (printf, scanf). Но библиотечные функции используют только внутренние системные вызовы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...