C fopen против открытого
Вопрос
Есть ли какая-либо причина (кроме синтаксических), по которой вы хотели бы использовать
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
в этом списке неверен и сбивает с толку, потому что он не очень похож на другие.Теперь я продолжу игнорировать это, потому что важное различие здесь заключается в стандарте C. FILE *
и дескриптор файла, специфичный для ОС.
Есть четыре основные причины использовать fopen
вместо open
.
fopen
предоставляет вам буферизацию ввода-вывода, которая может оказаться намного быстрее, чем то, что вы делаетеopen
.fopen
выполняет перевод конца строки, если файл не открыт в двоичном режиме, что может быть очень полезно, если ваша программа когда-либо портировалась в среду, отличную от Unix.- А
FILE *
дает вам возможность использоватьfscanf
и другие функции stdio. - Возможно, когда-нибудь ваш код придется перенести на какую-нибудь другую платформу, которая поддерживает только ANSI C и не поддерживает
open
функция.
На мой взгляд, перевод окончания строки чаще мешает, чем помогает, а разбор fscanf
настолько слаб, что вы неизбежно откажетесь от него в пользу чего-то более полезного.
И большинство платформ, поддерживающих C, имеют open
функция.
Остается вопрос о буферизации.В местах, где вы в основном читаете или записываете файл последовательно, поддержка буферизации действительно полезна и значительно увеличивает скорость.Но это может привести к некоторым интересным проблемам, когда данные не попадают в файл, когда вы ожидаете, что они там будут.Вы должны помнить, чтобы fclose
или fflush
в подходящее время.
Если вы выполняете поиск (он же fsetpos
или fseek
второй из которых немного сложнее использовать в соответствии со стандартами), полезность буферизации быстро снижается.
Конечно, я склонен много работать с сокетами, и тот факт, что вы действительно хотите выполнять неблокирующий ввод-вывод (который FILE *
совершенно не поддерживает каким-либо разумным способом) вообще без буферизации и часто сложные требования к синтаксическому анализу действительно окрашивают мое восприятие.
Другие советы
open()
это низкоуровневый вызов ОС. fdopen()
преобразует файловый дескриптор уровня операционной системы в FILE-абстракцию более высокого уровня языка C. fopen()
звонки open()
в фоновом режиме и напрямую дает вам указатель на ФАЙЛ.
Использование объектов FILE по сравнению с необработанными файловыми дескрипторами имеет ряд преимуществ, включая большую простоту использования, а также другие технические преимущества, такие как встроенная буферизация.В частности, буферизация обычно приводит к значительному увеличению производительности.
fopen против открытия в C
1) fopen
это библиотечная функция пока open
это системный вызов.
2) fopen
обеспечивает буферизованный ввод-вывод что быстрее по сравнению с open
который без буферизации.
3) fopen
является портативный пока open
нет портативный (открытость зависит от среды).
4) fopen
возвращает указатель на Структура ФАЙЛА(ФАЙЛ *); open
возвращает целое число, идентифицирующее файл.
5) А FILE *
дает вам возможность использовать fscanf и другие функции stdio.
Если у тебя есть 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) ;
открыть() будет вызываться в конце каждого из fopen() семейные функции. открыть() это системный вызов и fopen() предоставляются библиотеками в качестве функций-оболочек для простоты использования пользователем.
open()
— это системный вызов, специфичный для систем на базе Unix, который возвращает дескриптор файла.Вы можете записать в дескриптор файла, используя write()
это еще один системный вызов.
fopen()
— это вызов функции ANSI C, который возвращает указатель файла и переносим на другие операционные системы.Мы можем записать указатель файла, используя fprintf
.
В Юникс:
Вы можете получить указатель файла из дескриптора файла, используя:
fP = fdopen(fD, "a");
Вы можете получить дескриптор файла из указателя файла, используя:
fD = fileno (fP);
Зависит также от того, какие флаги требуются для открытия.Что касается использования для записи и чтения (и переносимости), следует использовать f*, как утверждалось выше.
Но если вы хотите указать больше, чем стандартные флаги (например, флаги rw и добавления), вам придется использовать API-интерфейс для конкретной платформы (например, POSIX open) или библиотеку, которая абстрагирует эти детали.В стандарте C таких флагов нет.
Например, вы можете захотеть открыть файл только в том случае, если он завершится.Если вы не укажете флаг создания, файл должен существовать.Если вы добавите эксклюзивный файл для создания, файл будет создан только в том случае, если он не существует.Есть еще много других.
Например, в системах Linux есть интерфейс светодиодов, доступный через sysfs.Он выставляет яркость светодиода через файл.Запись или чтение числа в виде строки в диапазоне от 0 до 255.Конечно, вы не хотите создавать этот файл и писать в него только в том случае, если он существует.Самое крутое теперь:Используйте fdopen для чтения/записи этого файла, используя стандартные вызовы.
Я перешел на open() с fopen() для своего приложения, потому что fopen вызывал двойное чтение каждый раз, когда я запускал fopen fgetc .Двойное чтение мешало тому, чего я пытался достичь.open(), похоже, делает то, что вы от него просите.
открытие файла с помощью открыть
Прежде чем мы сможем прочитать (или записать) информацию из (в) файла на диске, мы должны открыть файл.чтобы открыть файл, мы вызвали функцию 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.
это способ поведения открыть функция
Во время процесса буферизации есть некоторые причины: время ожидания может истечь.так что сравнивая открыть(высокоуровневый ввод-вывод) для открыть (низкоуровневый ввод-вывод), и это более быстрый и более подходящий вариант, чем открыть.