Відповіді:
Дескриптор файлу - це ціле число "ручка" низького рівня, яке використовується для ідентифікації відкритого файлу (або сокета або будь-якого іншого) на рівні ядра в Linux та інших системах, схожих на Unix.
Проходьте «голі» дескриптори файлів реальних викликів Unix, наприклад read()
, write()
і так далі.
FILE
Покажчик являє собою стандартну бібліотеку рівня конструкт C, використовуваний для подання файла. FILE
Обгортання дескриптор файлу, і додає буферизацию і інші функції , щоб зробити / O простіше я.
Ви передаєте FILE
покажчики на стандартні функції C, такі як fread()
і fwrite()
.
fd
це перший аргумент read()
. Чому ви називаєте це оголеним?
FILE *
типом бібліотеки , дескриптор цілочисельних файлів "менш завершений", тобто "голий".
Один буферний ( FILE *
), а другий - ні. На практиці ви хочете використовувати FILE *
майже завжди, коли ви читаєте з "реального" файлу (тобто на диску), якщо ви не знаєте, що ви робите, або якщо ваш файл насправді не є сокетом.
Ви можете отримати дескриптор файлу з FILE *
використанням, fileno()
а ви можете відкрити буферизацію FILE *
з дескриптора файлів за допомогоюfdopen()
Дескриптор файлу - це лише ціле число, яке ви отримуєте від open()
дзвінка POSIX . Використовуючи стандартний C, fopen()
ви отримуєте FILE
структуру назад. FILE
Структура містить цей дескриптор файлу серед інших речей , таких як кінець з файлу і індикатора помилки, положення потоку і т.д.
Тож використання fopen()
дає певну кількість абстракцій порівняно з open()
. Як правило, ви повинні використовувати, fopen()
оскільки це більш портативно, і ви можете використовувати всі інші стандартні функції C, які використовують FILE
структуру, тобто fprintf()
сім'ю.
Немає проблем із продуктивністю, що використовує будь-яку.
Дескриптор файлу проти вказівника на файл
Дескриптор файлу:
Дескриптор файлу - ціле значення, повернене open()
системним викликом.
int fd = open (filePath, mode);
Покажчик файлу:
Файл Покажчик являє собою покажчик на структуру C , повернутої fopen()
бібліотечної функцією, яка використовується для ідентифікації файлу, обгорткового дескриптор файлу, буферної функціональність і все інших функціональних можливостей, необхідних для введення / виведення операція .The покажчик файлу має типу 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;
Хочете додати бали, які можуть бути корисними.
ПРО FILE *
Я використовую його багато разів для налагодження журналів. наприклад,
FILE *fp;
fp = fopen("debug.txt","a");
fprintf(fp,"I have reached till this point");
fclose(fp);
ПРО FILE DESCRIPTOR
Зазвичай використовується для IPC.
Дає низькорівневий контроль файлам у * nix системах (пристроях, файлах, сокетах тощо), отже, більш потужним, ніж на FILE *
.
fdopen()
такі речі, як IPC та пристрої FILE*
?
FILE*
, але ви можете створити FILE*
з дескриптора файлу (fdopen()
), а пізніше закриття символу FILE
також закриє дескриптор. Тому ви можете робити IPC, але вам доведеться трохи попрацювати з дескрипторами файлів, щоб полегшити будь-який прямий IPC.
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 () та створення файлів .
fopen_s
це здається недоступним POSIX
, я припускаю, що найпотужніша думка була б до того open(2)
часу fdopen(2)
. (залишаючи вікна вбік). Крім того, що було б швидше fopen_s()
чи open(2)
за яким слід fdopen(2)
?
Системні виклики здебільшого використовують дескриптор файлів, наприклад, read
та write
. Функція бібліотеки використовуватиме покажчики файлів ( printf
, scanf
). Але функції бібліотеки використовують лише внутрішньо системні дзвінки.
Я знайшов хороший ресурс тут , що дає докладний огляд відмінностей між ними:
Коли ви хочете зробити введення чи виведення у файл, у вас є вибір двох основних механізмів представлення зв'язку між вашою програмою та файлом: дескриптори файлів та потоки. Дескриптори файлів представлені у вигляді об'єктів типу int, а потоки представлені у вигляді FILE * об'єктів.
Дескриптори файлів забезпечують примітивний низькорівневий інтерфейс для операцій введення та виводу. І дескриптори файлів, і потоки можуть представляти з'єднання з пристроєм (наприклад, терміналом) або трубою або сокетом для зв'язку з іншим процесом, а також звичайним файлом. Але, якщо ви хочете виконувати керуючі операції, характерні для певного виду пристроїв, ви повинні використовувати дескриптор файлу; не існує засобів, щоб використовувати потоки таким чином. Ви також повинні використовувати дескриптори файлів, якщо вашій програмі потрібно робити введення або виведення в спеціальних режимах, таких як неблокуючий (або опитуваний) вхід (див. Прапори статусу файлу).
Потоки забезпечують інтерфейс вищого рівня, напластований поверх примітивних приміток дескриптора файлів. Інтерфейс потоку дуже добре обробляє всі типи файлів - єдиним винятком є три стилі буферизації, які ви можете обрати (див. Потокове завантаження).
Основна перевага використання інтерфейсу потоку полягає в тому, що набір функцій для виконання фактичних операцій вводу і виводу (на відміну від операцій управління) на потоках набагато багатший і потужніший, ніж відповідні засоби для дескрипторів файлів. Інтерфейс дескриптора файлів забезпечує лише прості функції для передачі блоків символів, але інтерфейс потоку також забезпечує потужні відформатовані функції введення та виведення (printf і scanf), а також функції введення та виведення, орієнтованих на символи та лінії.
Оскільки потоки реалізовані з точки зору дескрипторів файлів, ви можете витягнути дескриптор файлу з потоку і виконувати операції низького рівня безпосередньо на дескрипторі файлу. Ви також можете спочатку відкрити з'єднання як дескриптор файлу, а потім зробити потік, пов’язаний з цим дескриптором файлу.
Взагалі, вам слід дотримуватися потоків, а не дескрипторів файлів, якщо ви не хочете виконати якусь конкретну операцію, яку можна виконати лише в дескрипторі файлу. Якщо ви починаючий програміст і не знаєте, які функції використовувати, пропонуємо сконцентруватися на форматованих функціях введення (див. Форматований вхід) та відформатованих функціях виводу (див. Форматизований вихід).
Якщо вас турбує переносимість ваших програм до інших систем, крім GNU, ви також повинні знати, що дескриптори файлів не такі портативні, як потоки. Ви можете сподіватися, що будь-яка система, що працює під керуванням ISO C, підтримує потоки, але системи, що не належать до GNU, можуть взагалі не підтримувати дескриптори файлів або можуть реалізовувати лише підмножину функцій GNU, які працюють на дескрипторах файлів. Більшість функцій дескриптора файлів у бібліотеці GNU C включені до стандарту POSIX.1.