I\'m doing a small project in C after quite a long time away from it. These happen to include some file handling. I noticed in various documentation that there are functions
read() & write() use unbuffered I/O. (fd: integer file descriptor)
fread() & fwrite() use buffered I/O. (FILE* structure pointer)
Binary data written to a pipe with write() may not be able to read binary data with fread(), because of byte alignments, variable sizes, etc. Its a crap-shoot.
Most low-level device driver code uses unbuffered I/O calls.
Most application level I/O uses buffered.
Use of the FILE* and its associated functions is OK on a machine-by-machine basis: but portability is lost on other architectures in the reading and writing of binary data. fwrite() is buffered I/O and can lead to unreliable results if written for a 64 bit architecture and run on a 32bit; or (Windows/Linux). Most OSs have compatibility macros within their own code to prevent this.
For low-level binary I/O portability read() and write() guarantee the same binary reads and writes when compiled on differing architectures. The basic thing is to pick one way or the other and be consistent about it, throughout the binary suite.
// mostly FILE* some fd input/output parameters for compatibility
// gives you a lot of helper functions -->
List of Functions
Function Description
───────────────────────────────────────────────────────────────────
clearerr check and reset stream status
fclose close a stream
fdopen stream open functions //( fd argument, returns FILE*) feof check and reset stream status
ferror check and reset stream status
fflush flush a stream
fgetc get next character or word from input stream
fgetpos reposition a stream
fgets get a line from a stream
fileno get file descriptor // (FILE* argument, returns fd)
fopen stream open functions
fprintf formatted output conversion
fpurge flush a stream
fputc output a character or word to a stream
fputs output a line to a stream
fread binary stream input/output
freopen stream open functions
fscanf input format conversion
fseek reposition a stream
fsetpos reposition a stream
ftell reposition a stream
fwrite binary stream input/output
getc get next character or word from input stream
getchar get next character or word from input stream
gets get a line from a stream
getw get next character or word from input stream
mktemp make temporary filename (unique)
perror system error messages
printf formatted output conversion
putc output a character or word to a stream
putchar output a character or word to a stream
puts output a line to a stream
putw output a character or word to a stream
remove remove directory entry
rewind reposition a stream
scanf input format conversion
setbuf stream buffering operations
setbuffer stream buffering operations
setlinebuf stream buffering operations
setvbuf stream buffering operations
sprintf formatted output conversion
sscanf input format conversion
strerror system error messages
sys_errlist system error messages
sys_nerr system error messages
tempnam temporary file routines
tmpfile temporary file routines
tmpnam temporary file routines
ungetc un-get character from input stream
vfprintf formatted output conversion
vfscanf input format conversion
vprintf formatted output conversion
vscanf input format conversion
vsprintf formatted output conversion
vsscanf input format conversion
So for basic use I would personally use the above without mixing idioms too much.
By contrast,
write()
lseek()
close()
pipe()
open()
creat()
fcntl()
all use file descriptors.
These provide fine-grained control over reading and writing bytes (recommended for special devices and fifos (pipes) ).
So again, use what you need, but keep consistent in your idioms and interfaces. If most of your code base uses one mode , use that too, unless there is a real reason not to. Both sets of I/O library functions are extremely reliable and used millions of times a day.
note-- If you are interfacing C I/O with another language, (perl, python, java, c#, lua ...) check out what the developers of those languages recommend before you write your C code and save yourself some trouble.