Закрыть дескриптор файла и затем использовать его
Ниже приведен фрагмент кода, который объясняет системный вызов dup2. Что я не понимаю, так это то, что после дублирования обоих файловых дескрипторов нам нужно закрыть старый файловый дескриптор. Поскольку дескриптор "out" теперь закрыт, как сообщение, отправленное на stdout_fileno, также записывается в "out". Обратите внимание, что код был написан не мной.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(){
int out;
out=open("out",O_WRONLY | O_TRUNC | O_CREAT,S_IRUSR|S_IRGRP | S_IWGRP | S_IWUSR);
dup2(out,STDOUT_FILENO);
close(out);
printf("now this should be written to a file called out \n");
return 0;
}
3 ответа
почему нам нужно закрыть старый файловый дескриптор
Вам действительно не нужно; Пример в основном показывает, что вы можете. Тем не менее, каждый процесс в системе Unix имеет ограниченное количество файловых дескрипторов, и если у вас есть два из них, ссылающихся на один и тот же файл, один из них не нужен, так что вы можете также закрыть его.
Поскольку дескриптор "out" теперь закрыт, как сообщение, отправленное на stdout_fileno, также записывается в "out".
Потому что после dup2
, STDOUT_FILENO
также ссылается на этот файл, и закрытие fd не закрывает его клонов.
Если у вас есть два дескриптора, указывающих на один и тот же файл, запись в оба приведет к случайному смешиванию вывода; но нет ошибки, которую вы можете обнаружить (т.е. запись будет успешной), чтобы сказать, что что-то не так.
Если вы проверяете возвращаемые значения, вы можете легко обнаружить попытки записи в закрытый файловый дескриптор, поэтому лучше закрыть тот, который вы не используете, а не хранить его и быть осторожным, чтобы никогда не трогать его.
stdout, stdin, stderr, все файлы в системах *nix. Вы можете думать о своем коде как о том, что вы берете "указатель" на файл и устанавливаете stdout, чтобы указать на этот файл. В этот момент первый "указатель" может быть удален. Это также, почему он использует prinft(); а не fprintf();
Вам не нужно закрывать старый файловый дескриптор, но код, вероятно, предназначен для примера, показывающего, что вы можете.
Как говорилось в двух других ответах, в целом, вероятно, лучше иметь открытый дескриптор файла, так как это сокращает объем ресурсов, используемых вашей программой, и упрощает понимание того, что вы работаете с одним файлом. (например, у вас могут быть проблемы с записью и чтением из этого файла в цикле)