Есть ли какая-либо причина (кроме синтаксических), которую вы хотите использовать
FILE *fdopen(int fd, const char *mode);
или
FILE *fopen(const char *path, const char *mode);
вместо
int open(const char *pathname, int flags, mode_t mode);
при использовании C в среде Linux?
Во-первых, нет особой причины использовать fdopen
если fopen
является опцией, а open
- другой возможный выбор. Вы не должны были использовать open
чтобы открыть файл, если вы хотите FILE *
. Поэтому включение fdopen
в этот список неверно и сбивает с толку, потому что оно не очень похоже на другие. Теперь я перейду к его игнорированию, потому что важное различие здесь - между стандартным FILE *
C FILE *
и дескриптором файла, специфичным для ОС.
Есть четыре основные причины использовать fopen
вместо open
.
fopen
обеспечивает буферизацию ввода-вывода, которая может оказаться намного быстрее, чем то, что вы делаете с open
.fopen
выполняет перевод конца строки, если файл не открывается в двоичном режиме, что может быть очень полезно, если ваша программа портирована в не-Unix среду.FILE *
дает вам возможность использовать fscanf
и другие функции stdio.open
. На мой взгляд, перевод конца строки чаще встречается у вас на пути, чем помогает, а синтаксический анализ fscanf
настолько слаб, что вы неизбежно в конечном итоге выбрасываете его в пользу чего-то более полезного.
И большинство платформ, поддерживающих C, имеют open
функцию.
Это оставляет вопрос буферизации. В местах, где вы в основном читаете или пишете файл последовательно, поддержка буферизации действительно полезна и значительно повышает скорость. Но это может привести к некоторым интересным проблемам, при которых данные не попадают в файл, когда вы ожидаете, что они там будут. Вы должны помнить fclose
или fflush
в подходящее время.
Если вы выполняете поиск (то есть fsetpos
или fseek
второй из которых немного сложнее использовать в соответствии со стандартами), полезность буферизации быстро снижается.
Конечно, мой уклон заключается в том, что я склонен много работать с сокетами, и есть тот факт, что вы действительно хотите делать неблокирующий ввод-вывод (который FILE *
полностью не поддерживает каким-либо разумным способом) без какой-либо буферизации и часто сложные требования синтаксического анализа действительно окрашивают мое восприятие.
open()
- это низкоуровневый вызов os. fdopen()
преобразует дескриптор файла os-уровня в FILE-абстракцию языка C более высокого уровня. fopen()
вызывает open()
в фоновом режиме и дает вам FILE-указатель напрямую.
Существует несколько преимуществ использования файловых дескрипторов FILE-объектов, а также простота использования, а также другие технические преимущества, такие как встроенная буферизация. Особенно буферизация обычно приводит к значительному повышению производительности.
fopen vs open в C
1) fopen
является библиотечной функцией, а open
является системным вызовом .
2) fopen
обеспечивает буферизованный IO, который быстрее сравнивается с open
, который не буферизирован.
3) fopen
переносимый, а open
не переносимый (open - это специфический для среды).
4) fopen
возвращает указатель на структуру FILE (FILE *); open
возвращает целое число, идентифицирующее файл.
5) A FILE *
дает вам возможность использовать fscanf и другие функции stdio.
open
это стандарт POSIX, так что он довольно переносимый
Если у вас есть FILE *
, вы можете использовать такие функции, как fscanf
, fprintf
и fgets
и т.д. Если у вас есть только дескриптор файла, вы ограничены (но, скорее, быстрее) процедуры ввода и вывода read
, write
и т.д.
Если вы не являетесь частью 0.1% приложений, где использование open
является фактическим преимуществом производительности, действительно нет веской причины не использовать fopen
. Что касается fdopen
, если вы не играете с файловыми дескрипторами, вам не нужен этот вызов.
Придерживайтесь fopen
и его семейства методов (fwrite
, fread
, fprintf
и др.), и вы будете очень довольны. Также важно, что другие программисты будут довольны вашим кодом.
Использование open, read, write означает, что вам приходится беспокоиться о взаимодействии с сигналами.
Если вызов был прерван обработчиком сигнала, функции возвратят -1 и установите errno в EINTR.
Таким образом, правильный способ закрыть файл будет
while (retval = close(fd), retval == -1 && ernno == EINTR) ;
close
это зависит от операционной системы. Неправильно выполнять цикл в Linux, AIX и некоторых других операционных системах.
open() будет вызываться в конце каждой из семейных функций fopen(). open() - системный вызов, а fopen() предоставляются библиотеками в качестве функций обертки для удобства пользователя
open()
- системный вызов, специфичный для Unix-систем, и он возвращает дескриптор файла. Вы можете записать в дескриптор файла, используя write()
который является другим системным вызовом. fopen()
- это вызов функции ANSI C, который возвращает указатель на файл и переносим на другие ОС. Мы можем записать указатель в файл, используя fprintf
.
В Unix:
Вы можете получить указатель файла из дескриптора файла, используя:
fP = fdopen(fD, "a");
Вы можете получить дескриптор файла из указателя файла, используя:
fD = fileno (fP);
Зависит также от того, какие флаги необходимы для открытия. В отношении использования для записи и чтения (и переносимости) f * следует использовать, как указано выше.
Но если в основном вы хотите указать больше стандартных флагов (например, флагов rw и append), вам придется использовать API-интерфейс платформы (например, POSIX open) или библиотеку, которая абстрагирует эти детали. В C-стандарте нет таких флагов.
Например, вы можете открыть файл, только если он выйдет. Если вы не укажете флаг создания, файл должен существовать. Если вы добавите эксклюзив для создания, он создаст файл только в том случае, если он не существует. Есть еще много.
Например, в системах Linux есть интерфейс интерфейса, открытый через sysfs. Он отображает яркость светодиода через файл. Запись или чтение числа в виде строки в диапазоне от 0 до 255. Конечно, вы не хотите создавать этот файл и писать только в том случае, если он существует. Теперь классная вещь: используйте fdopen для чтения/записи этого файла с помощью стандартных вызовов.
Я изменил на open() из fopen() для моего приложения, потому что fopen вызывал двойные чтения каждый раз, когда я запускал fopen fgetc. Двойное чтение искажало то, что я пытался выполнить. open() просто делает то, что вы просите об этом.
открытие файла с помощью fopen
прежде чем мы сможем прочитать (или записать) информацию из (на) файла на диске, мы должны открыть файл. чтобы открыть файл, который мы назвали функцией fopen.
1.firstly it searches on the disk the file to be opened.
2.then it loads the file from the disk into a place in memory called buffer.
3.it sets up a character pointer that points to the first character of the buffer.
это способ поведения функции fopen
есть некоторые причины при буферизации, это может быть тайм-аут. поэтому при сравнении fopen (высокоуровневый i/o) с системным вызовом open (низкоуровневый i/o), и это быстрее, чем fopen.
fdopen
видуfdopen
иopen
илиfopen
иopen
?