Reputation: 6444
Is there any reason (other than syntactic ones) that you'd want to use
FILE *fdopen(int fd, const char *mode);
or
FILE *fopen(const char *path, const char *mode);
instead of
int open(const char *pathname, int flags, mode_t mode);
when using C in a Linux environment?
Upvotes: 286
Views: 262223
Reputation: 11
I think this question has been answered adequately already but its an interesting question so let me throw in my 2 cents. I think open()
sits closer to the OS kernel and is lower level than the fopen()
function. The open()
function is part of the POSIX standard and could be preferable in a few situations. If you are developing Linux drivers or want to do non-blocking IO on POSIX compliant systems, you'll want to use open()
instead of fopen()
. However, if all you want is cross platform file I/O which works on both Linux and Windows, fopen()
would be a better choice.
Upvotes: 0
Reputation: 56038
Of those, fdopen
is not like the others. fdopen
is what you would use if you first called open
and then wanted a FILE *
. There is no sense doing that if you have the choice to just call fopen
instead. There are cases where you won't be able to get fopen
to do exactly what you want, but they're outside the scope of this question.
So, let's just pretend fdopen
isn't even there and get on with the question.
There are four main reasons to use fopen
instead of open
.
fopen
provides you with buffering IO that may turn out to be a lot faster than what you're doing with open
.fopen
does line ending translation if the file is not opened in binary mode, which can be very helpful if your program is ever ported to a non-Unix environment (though the world appears to be converging on LF-only (except IETF text-based networking protocols like SMTP and HTTP and such)).FILE *
gives you the ability to use fscanf
and other stdio functions.open
function.In my opinion (and experience) the line ending translation more often gets in your way than helps you, and the parsing of fscanf
is so weak that you inevitably end up tossing it out in favor of something more useful.
And most platforms that support C have an open
function.
That leaves the buffering question. In places where you are mainly reading or writing a file sequentially, the buffering support is really helpful and a big speed improvement. But it can lead to some interesting problems in which data does not end up in the file when you expect it to be there. You have to remember to fclose
or fflush
at the appropriate times.
If you're doing seeks (aka fsetpos
or fseek
the second of which is slightly trickier to use in a standards compliant way), the usefulness of buffering quickly goes down.
Of course, my bias is that I tend to work with sockets a whole lot, and there the fact that you really want to be doing non-blocking IO (which FILE *
totally fails to support in any reasonable way) with no buffering at all and often have complex parsing requirements really color my perceptions.
Upvotes: 304
Reputation: 2885
fopen
vs open
in C
fopen
is a library function while open
is a system call.
fopen
provides buffered IO which may be faster compared to open
which is non-buffered.
fopen
is portable while open
not portable (open
is environment specific).
fopen
returns a pointer to a FILE
structure (FILE *
) while open
returns an integer that identifies the file.
A FILE *
gives you the ability to use fscanf
and other stdio.h
functions.
Upvotes: 70
Reputation: 107
fopen
Before we can read(or write) information from (to) a file on disk, we must open the file. To open the file, we call the function fopen()
.
fopen()
searches the disk for the file to be opened.char
) pointer that points to the first character of the buffer.Sometimes, during the buffering process, fopen()
may time out.
So, when comparing the fopen()
library call (high-level i/o) to the open()
(low-level i/o) system call, it is faster and more appropriate to use open()
rather than fopen()
.
Upvotes: -1
Reputation: 1141
open()
is a system call and specific to Unix-based systems and it returns a file descriptor. You can write to a file descriptor using write()
which is another system call.
fopen()
is an ANSI C function call which returns a file pointer and it is portable to other OSes. We can write to a file pointer using fprintf
.
In Unix:
You can get a file pointer from the file descriptor using:
fP = fdopen(fD, "a");
You can get a file descriptor from the file pointer using:
fD = fileno (fP);
Upvotes: 10
Reputation: 64068
Unless you're part of the 0.1% of applications where using open
is an actual performance benefit, there really is no good reason not to use fopen
. As far as fdopen
is concerned, if you aren't playing with file descriptors, you don't need that call.
Stick with fopen
and its family of methods (fwrite
, fread
, fprintf
, et al) and you'll be very satisfied. Just as importantly, other programmers will be satisfied with your code.
Upvotes: 21
Reputation: 206
Depends also on what flags are required to open. With respect to usage for writing and reading (and portability) f* should be used, as argued above.
But if basically want to specify more than standard flags (like rw and append flags), you will have to use a platform specific API (like POSIX open) or a library that abstracts these details. The C-standard does not have any such flags.
For example you might want to open a file, only if it exits. If you don't specify the create flag the file must exist. If you add exclusive to create, it will only create the file if it does not exist. There are many more.
For example on Linux systems there is a LED interface exposed through sysfs. It exposes the brightness of the led through a file. Writing or reading a number as a string ranging from 0-255. Of course you don't want to create that file and only write to it if it exists. The cool thing now: Use fdopen to read/write this file using the standard calls.
Upvotes: 3
Reputation: 1664
open() will be called at the end of each of the fopen() family functions. open() is a system call and fopen() are provided by libraries as a wrapper functions for user easy of use
Upvotes: 3
Reputation: 71
I changed to open() from fopen() for my application, because fopen was causing double reads every time I ran fopen fgetc . Double reads were disruptive of what I was trying to accomplish. open() just seems to do what you ask of it.
Upvotes: 7
Reputation: 2903
Using open, read, write means you have to worry about signal interaptions.
If the call was interrupted by a signal handler the functions will return -1 and set errno to EINTR.
So the proper way to close a file would be
while (retval = close(fd), retval == -1 && ernno == EINTR) ;
Upvotes: 8
Reputation: 40230
open()
is a low-level os call. fdopen()
converts an os-level file descriptor to the higher-level FILE-abstraction of the C language. fopen()
calls open()
in the background and gives you a FILE-pointer directly.
There are several advantages to using FILE-objects rather raw file descriptors, which includes greater ease of usage but also other technical advantages such as built-in buffering. Especially the buffering generally results in a sizeable performance advantage.
Upvotes: 78
Reputation: 95315
If you have a FILE *
, you can use functions like fscanf
, fprintf
and fgets
etc. If you have just the file descriptor, you have limited (but likely faster) input and output routines read
, write
etc.
Upvotes: 11