Есть ли какая-либо причина (кроме синтаксической), которую вы хотели бы использовать
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
иopen
или илиfopen
иopen
?fopen
является частью стандартной библиотеки C,open
нет. Используйтеfopen
при написании переносимого кода.open
хотя это функция POSIX.Ответы:
Во-первых, нет особенно веской причины использовать
fdopen
iffopen
как вариант, так иopen
другой возможный выбор. Вы не должныopen
были открывать файл, если хотитеFILE *
. Поэтому включениеfdopen
в этот список неверно и запутанно, потому что оно не очень похоже на другие. Теперь я перейду к его игнорированию, потому что здесь важно различать стандарт CFILE *
и дескриптор файла, специфичный для ОС.Есть четыре основные причины для использования
fopen
вместоopen
.fopen
обеспечивает буферизацию ввода-вывода, которая может оказаться намного быстрее, чем то, что вы делаетеopen
.fopen
выполняет перевод строки, если файл не открывается в двоичном режиме, что может быть очень полезно, если ваша программа портирована в не-Unix-среду (хотя кажется, что мир сходится только на LF (кроме текстовой сети IETF) протоколы типа SMTP и HTTP и такие)).FILE *
дает вам возможность использоватьfscanf
и другие функции stdio.open
функцию.На мой взгляд, перевод конца строки чаще встречается у вас на пути, чем помогает, а синтаксический анализ
fscanf
настолько слаб, что вы неизбежно в конечном итоге выбрасываете его в пользу чего-то более полезного.И большинство платформ, поддерживающих C, имеют
open
функцию.Это оставляет вопрос буферизации. В местах, где вы в основном читаете или пишете файл последовательно, поддержка буферизации действительно полезна и значительно повышает скорость. Но это может привести к некоторым интересным проблемам, при которых данные не попадают в файл, когда вы ожидаете, что они там будут. Вы должны помнить
fclose
илиfflush
в соответствующее время.Если вы выполняете поиск (иначе,
fsetpos
илиfseek
второй, который немного сложнее использовать в соответствии со стандартами), полезность буферизации быстро снижается.Конечно, мой уклон заключается в том, что я склонен много работать с сокетами, и есть тот факт, что вы действительно хотите делать неблокирующий ввод-вывод (который
FILE *
полностью не поддерживается каким-либо разумным способом) без какой-либо буферизации и часто сложные требования синтаксического анализа действительно окрашивают мое восприятие.источник
fgets
,fgetc
,fscanf
,fread
), всегда будет читать весь размер буфера (4K, 8K или как вы установите). Используя прямой ввод / вывод, вы можете избежать этого. В этом случае даже лучше использоватьpread
вместо пары поиск / чтение (1 системный вызов вместо 2).read()
иwrite()
вызовов является удобной пятой причиной использования семейства функций libc.ioctl
также поддерживаютfileno
вызов, который принимаетFILE *
и возвращает номер, который можно использовать вioctl
вызове. Будьте осторожны, хотя.FILE *
связанные вызовы могут неожиданно взаимодействовать с использованиемioctl
для изменения чего-либо в базовом файловом дескрипторе.open()
это вызов низкого уровня.fdopen()
преобразует файловый дескриптор уровня os в FILE-абстракцию более высокого уровня языка C.fopen()
вызываетopen()
в фоновом режиме и дает вам FILE-указатель напрямую.Есть несколько преимуществ использования FILE-объектов, а не сырых файловых дескрипторов, что включает в себя большую простоту использования, но также и другие технические преимущества, такие как встроенная буферизация. В частности, буферизация обычно дает значительное преимущество в производительности.
источник
fopen()
не обеспечивает одинаковый уровень контроля при открытии файлов, например, создает разрешения, режимы совместного использования и многое другое. как правило,open()
и варианты обеспечивают гораздо больший контроль, близкий к тому, что на самом деле обеспечивает операционная системаmmap
файл и вносите изменения с помощью обычного ввода-вывода (как бы невероятно это ни звучало на самом деле, как в нашем проекте и по очень веским причинам), буферизация была бы на пути.Fopen против открытого в C
1)
fopen
является библиотечной функцией, покаopen
является системным вызовом .2)
fopen
обеспечивает буферный ввод - вывод , который быстрее , по сравнению сopen
которым это не буферизацией .3)
fopen
является переносным, ноopen
не переносимым ( открытый характерен для конкретной среды ).4)
fopen
возвращает указатель на структуру FILE (FILE *) ;open
возвращает целое число, идентифицирующее файл.5) A
FILE *
дает вам возможность использовать fscanf и другие функции stdio.источник
open
это стандарт POSIX, так что он вполне переносимЕсли вы не являетесь частью 0,1% приложений, где использование
open
является фактическим выигрышем в производительности, на самом деле нет веских причин не использовать егоfopen
. Что касаетсяfdopen
вопроса, если вы не играете с файловыми дескрипторами, вам не нужен этот вызов.Палка с
fopen
и его семейство методов (fwrite
,fread
,fprintf
, и др) , и вы будете очень довольны. Не менее важно, что другие программисты будут довольны вашим кодом.источник
Если у вас есть
FILE *
, вы можете использовать такие функции , какfscanf
,fprintf
иfgets
т.д. Если у вас есть только дескриптор файла, вы ограничены (но , вероятно , быстрее) подпрограммы ввода и выводаread
, иwrite
т.д.источник
Использование open, read, write означает, что вам нужно беспокоиться о сигнальных взаимодействиях.
Если вызов был прерван обработчиком сигнала, функции вернут -1 и установят errno в EINTR.
Таким образом, правильный способ закрыть файл будет
источник
close
это зависит от операционной системы. Неправильно выполнять цикл в Linux, AIX и некоторых других операционных системах.open()
это системный вызов, специфичный для Unix-систем, и он возвращает дескриптор файла. Вы можете записать в дескриптор файла, используяwrite()
другой системный вызов.fopen()
это вызов функции ANSI C, который возвращает указатель на файл и переносим на другие ОС. Мы можем записать в файл указатель, используяfprintf
.В Unix:
Вы можете получить указатель файла из файлового дескриптора, используя:
Вы можете получить дескриптор файла из указателя файла, используя:
источник
open () будет вызываться в конце каждой из функций семейства fopen () . open () - это системный вызов, а fopen () предоставляются библиотеками в качестве функций-оболочек для простоты использования.
источник
Я переключился на open () из fopen () для моего приложения, потому что fopen вызывал двойное чтение каждый раз, когда я запускал fopen fgetc. Двойное чтение мешало тому, чего я пытался достичь. open () просто делает то, о чем вы просите.
источник
Зависит также от того, какие флаги требуется открыть. Что касается использования для записи и чтения (и переносимости), следует использовать f *, как указано выше.
Но если в основном вы хотите указать больше, чем стандартные флаги (например, флаги rw и append), вам придется использовать специфичный для платформы API (например, открытый POSIX) или библиотеку, которая абстрагирует эти детали. Стандарт C не имеет таких флагов.
Например, вы можете открыть файл, только если он завершится. Если вы не укажете флаг создания, файл должен существовать. Если вы добавите эксклюзив для создания, он будет создавать файл, только если он не существует. Есть много других.
Например, в системах Linux есть светодиодный интерфейс, предоставляемый через sysfs. Это выставляет яркость ведомого через файл. Запись или чтение числа в виде строки в диапазоне от 0 до 255. Конечно, вы не хотите создавать этот файл и писать в него, только если он существует. Самое интересное: используйте fdopen для чтения / записи этого файла с помощью стандартных вызовов.
источник
Открыв файл с помощью fopen,
прежде чем мы сможем прочитать (или записать) информацию из (в) файла на диске, мы должны открыть файл. чтобы открыть файл мы вызвали функцию fopen.
При таком способе поведения функции fopen
существуют некоторые причины, пока процесс буферизации может истечь по таймауту. поэтому при сравнении системного вызова fopen (высокоуровневый ввод-вывод ) с открытым (низкоуровневый ввод-вывод) он оказывается более подходящим, чем fopen .
источник