В чем разница между файловым дескриптором и указателем файла?

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

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

9 ответов


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

вы передаете" голые " файловые дескрипторы фактическим вызовам Unix, таким как read(), write() и так далее.

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

передать FILE указатели на стандартные функции C, такие как fread() и fwrite().


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

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


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

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

нет проблем с производительностью, используя либо или.


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

о FILE *

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


файловый дескриптор vs указатель файла

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

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

int fd = open (filePath, mode);

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

файловый указатель:

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

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

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


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

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

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

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


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


в Unix и связанных с ним компьютерных операционных системах файловый дескриптор (FD, реже fildes) является абстрактным индикатором (дескриптором), используемым для доступа к файлу или другому ресурсу ввода/вывода, такому как трубопровод или сетевой сокет. Файловые дескрипторы являются частью интерфейса прикладного программирования POSIX. Файловый дескриптор является неотрицательным целым числом, хотя обычно он представлен на языке программирования C как тип int, отрицательные значения зарезервированы для указания "нет значения" или ошибки состояние.