В чем разница между файловым дескриптором и файловым указателем?
-
19-09-2019 - |
Вопрос
Я хочу знать разницу между файловым дескриптором и файловым указателем.
Кроме того, в каком сценарии вы бы использовали один вместо другого?
Решение
Файловый дескриптор - это низкоуровневый целочисленный "дескриптор", используемый для идентификации открытого файла (или сокета, или чего-либо еще) на уровне ядра в Linux и других Unix-подобных системах.
Вы передаете "голые" файловые дескрипторы фактическим вызовам Unix, таким как читать()
, написать()
и так далее.
A FILE
указатель - это конструкция уровня стандартной библиотеки языка Си, используемая для представления файла.В FILE
обертывает файловый дескриптор и добавляет буферизацию и другие функции для упрощения ввода-вывода.
Ты проходишь FILE
указатели на стандартные функции C , такие как фрейд()
и fwrite()
.
Другие советы
Один из них буферизован (FILE *
) а другой - нет.На практике вы хотите использовать FILE *
почти всегда, когда вы читаете из "реального" файла (т.е.на диске), если только вы не знаете, что делаете, или если ваш файл на самом деле не является сокетом или около того..
Вы можете получить дескриптор файла из FILE *
используя fileno()
и вы можете открыть буферизованный FILE *
из файлового дескриптора , используя fdopen()
Файловый дескриптор - это просто целое число, которое вы получаете из Posix' open()
звони.Используя стандартный C fopen()
вы получаете FILE
верните структуру обратно.В FILE
struct содержит дескриптор этого файла среди прочих вещей, таких как конец файла и индикатор ошибки, позиция потока и т.д.
Таким образом, используя fopen()
дает вам определенную степень абстракции по сравнению с open()
.В общем, вы должны использовать fopen()
поскольку это более переносимо, и вы можете использовать все другие стандартные функции C, которые используют FILE
структура, то есть fprintf()
и семья.
При использовании либо того, либо другого проблем с производительностью нет.
Файловый дескриптор против указателя на файл
Дескриптор файла:
Дескриптор файла - это целочисленное значение, возвращаемое open()
системный вызов.
int fd = open (filePath, mode);
- Обработчик низкого уровня / ядра.
- используйте для чтения() и записи() системных вызовов UNIX.
- Не включает буферизацию и подобные функции.
- Менее портативен и не обладает достаточной эффективностью.
Указатель на файл:
Указатель на файл - это указатель на структуру C, возвращаемую fopen()
библиотечная функция, которая используется для идентификация файла, перенос файлового дескриптора, функциональность буферизации и все другие функциональные возможности, необходимые для операций ввода-вывода.Указатель на файл имеет тип ФАЙЛ, определение которого можно найти в "/usr/включить/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;
- Это высокоуровневый интерфейс.
- Передается функциям fread() и fwrite().
- Включает буферизацию, индикацию ошибок и обнаружение EOF и т.д.
- Обеспечивает более высокую мобильность и эффективность.
Хочу добавить моменты, которые могут оказаться полезными.
о нас FILE *
- не может использоваться для межпроцессного взаимодействия (IPC).
- используйте его, когда вам нужен универсальный буферизованный ввод-вывод (printf, frpintf, snprintf, scanf).
Я использую его много раз для журналов отладки.пример,
FILE *fp; fp = fopen("debug.txt","a"); fprintf(fp,"I have reached till this point"); fclose(fp);
о нас FILE DESCRIPTOR
Обычно он используется для IPC.
Предоставляет низкоуровневый контроль над файлами в системах * nix.(устройства, файлы, сокеты и т.д.), Следовательно, более мощный, чем
FILE *
.
FILE *
более полезен при работе с текстовыми файлами и пользовательским вводом / выводом, поскольку он позволяет вам использовать функции API, такие как sprintf()
, sscanf()
, fgets()
, feof()
и т.д.
API файловых дескрипторов является низкоуровневым, поэтому он позволяет работать с сокетами, каналами, файлами, отображенными в память (и обычными файлами, конечно).
Просто заметка, чтобы закончить обсуждение (если интересно)....
fopen
может быть небезопасным, и вам, вероятно, следует использовать fopen_s
или open
с эксклюзивным набором битов.C1X предлагает x
режимы, чтобы вы могли fopen
с режимами "rx"
, "wx"
, и т.д.
Если вы используете open
, вы могли бы рассмотреть open(..., O_EXCL | O_RDONLY,... )
или open(..., O_CREAT | O_EXCL | O_WRONLY,... )
.
Смотрите, например, Не делайте предположений относительно fopen() и создания файла.
Системные вызовы в основном используют файловый дескриптор, например read
и write
.Библиотечная функция будет использовать указатели на файлы ( printf
, scanf
).Но библиотечные функции используют только внутренние системные вызовы.