Как получить указатель FILE из файлового дескриптора?

Я играю с mkstemp(), который предоставляет дескриптор файла, но я хочу генерировать форматированный вывод через fprintf(). Есть ли простой способ преобразовать файловый дескриптор, предоставленный mkstemp(), в структуру FILE *, подходящую для использования с fprintf()?


person BD at Rivenhill    schedule 21.12.2009    source источник


Ответы (3)


Используйте fdopen():

FILE* fp = fdopen(fd, "w");
person Richard Pennington    schedule 21.12.2009
comment
А чтобы получить дескриптор файла из ФАЙЛА *, используйте fileno(): linux.die.net/man/3 / fileno - person Lee Netherton; 17.10.2011
comment
если fd был открыт с некоторыми флагами (например, O_NONBLOCK) - что будет с ними после того, как fdopen откроет его с новыми флагами? Будут ли они объединены или заменены? - person xealits; 04.11.2015
comment
Недоступно в ANSI C. - person jww; 27.03.2016
comment
@jww: файловые дескрипторы изначально не соответствуют стандарту ANSI C. - person Rufflewind; 02.05.2016
comment
и есть ли способ закрыть файл с помощью fd? - person Jéssica Carneiro; 31.01.2017
comment
Если вы имеете в виду close (fd), это плохая идея. fclose (fp) следует использовать, чтобы убедиться, что любой буферизованный вывод (если есть) записан. - person Richard Pennington; 31.01.2017
comment
это плохо - звонить fdopen несколько раз? (при условии, что это происходит внутри некоторой функции, которая вызывается снова и снова) - person phil294; 05.07.2017
comment
Вы не хотите, чтобы fdopen () дважды выполнял один и тот же дескриптор файла. У каждого экземпляра будут отдельные буферы, из-за которых ваш ввод / вывод будет испорчен. - person Richard Pennington; 05.07.2017
comment
@RichardPennington Я думаю, что несколько вызовов fdopen - это нормально, в зависимости от того, что лежит в основе дескриптора файла. Для tty или сокета это может быть действительно желательно, поскольку ANSI C требует _2 _ / _ 3 _ / _ 4_ вызовов между вводом и выводом. Здесь кажется, что лучше всего использовать разные потоки для ввода и вывода. По сути, это в любом случае происходит с _5 _ / _ 6 _ / _ 7_ на терминальном устройстве - файловые дескрипторы ссылаются на одно и то же описание файла. См. experts-exchange.com/questions/24261206/ - person Graeme; 22.10.2017
comment
@xealits Параметры ФАЙЛА * должны находиться в пределах уже открытого файлового дескриптора. Поэтому, если вы открыли fd только для чтения, а FILE * только для записи, он должен вызвать исключение. Для получения дополнительной информации см. ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/ - person Tjad Clark; 06.12.2017
comment
@TjadClark он должен генерировать исключение - это было бы сложно, поскольку fdopen () - это функция C, а C не имеет собственного механизма исключений. - person Nick; 01.10.2018

FILE* f = fdopen(d, "w");

вывод man fdopen:

ОБЗОР

#include <stdio.h>

FILE *
fdopen(int fildes, const char *mode);

Функция fdopen() связывает поток с существующим файловым дескриптором fildes. Режим потока должен быть совместим с режимом дескриптора файла. Когда поток закрывается через fclose(3), закрывается и fildes.

person Gregory Pakosz    schedule 21.12.2009
comment
Недоступно в ANSI C. - person jww; 27.03.2016
comment
Для большей ясности обратитесь к ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/ - person Tjad Clark; 06.12.2017

Не существует стандартного способа сделать это (или наоборот), поскольку стандарт C ничего не говорит о файловых дескрипторах. Ваша конкретная платформа может предоставлять или не предоставлять такой механизм.

person Community    schedule 21.12.2009
comment
Зависит от того, что вы подразумеваете под стандартом. POSIX - это стандарт. - person Richard Pennington; 21.12.2009
comment
тем не менее, функция fdopen () соответствует стандарту IEEE Std 1003.1-1988 (`` POSIX.1 ''). - person Gregory Pakosz; 21.12.2009
comment
Вопрос был о файловых дескрипторах. ;-) - person Richard Pennington; 21.12.2009
comment
@Neil ›Возможно, ты прав, ты не помог ОП со своим ответом - person Gregory Pakosz; 21.12.2009
comment
@Gregory Я помог ему, предполагая, что он хочет писать переносимый код. А отрицать технически правильные ответы - не лучшая практика. - person ; 21.12.2009
comment
@Richard Вопрос помечен как C, а не Posix. Posix - это платформа, а не язык, стандарт. - person ; 21.12.2009
comment
@Neil ›Я не голосовал против, действительно, в том, что вы сказали, нет ничего плохого. - person Gregory Pakosz; 21.12.2009
comment
@Neil ›вопрос, помеченный как C, не означает, что я говорю правду о стандарте C, а скорее я кодирую на C, у меня не получается это сделать, скажите, возможно ли это и как? - person Gregory Pakosz; 21.12.2009
comment
Здесь, на SO, есть тег posix с 193 вопросами. Сказав это, я думаю, что ответ Нила правильный. Больше людей должны использовать тег posix. И напомнить людям, что такое C. Пока мы этим занимаемся, мы должны дать людям понять, что нет ничего лучше C / C ++ и что это два разных языка. - person Alok Singhal; 21.12.2009
comment
@Neil ›похоже, что у вас есть фанаты, так как некоторые из моих ответов сейчас проигрывают :) - person Gregory Pakosz; 21.12.2009
comment
Я медленно отступаю ... Теперь отворачиваюсь и убегаю. - person Richard Pennington; 21.12.2009
comment
@Gregory: Для записи, это был не я. Здесь, на SO, есть некоторые странные проблемы с голосованием против. Мои сообщения stackoverflow.com/questions/1898371 / и stackoverflow.com/questions/1938491/memory-corruption/ были отклонены, и я не знаю почему! - person Alok Singhal; 21.12.2009
comment
Я согласен с тем, что стандартного способа сделать это не существует, но упоминание mkstemp в OP подразумевает, что нестандартные решения приемлемы в данном конкретном случае. В этом случае, однако, он должен был добавить тег posix (который, как я вижу, с тех пор был добавлен). - person Emerick Rogul; 21.12.2009
comment
@Neil, а цель инета и смысл жизни. Было бы разумнее, если бы вы сказали, что придерживаетесь другого мнения. Я также сомневаюсь, что SO - это все, что касается стандартов. И не очень практично полагаться на навыки маркировки кого-то с SO-опытом, соответствующим репутации 23. - person Michael Krelin - hacker; 21.12.2009
comment
Не уверен, почему этого парня отвергают. ANSI C не имеет fdopen, поэтому нет способа преобразовать файловый дескриптор в FILE* в базовой системе. Чтобы получить функциональность, вам понадобится другой стандарт. - person jww; 27.03.2016