|Fundamental C - Files|
|Written by Harry Fairhead|
|Monday, 20 January 2020|
Page 1 of 3
This extract, from my new book on programming C in an IoT context, explains the basics of files the C way. As with all things C it starts simple and then gets a little more involved.
Fundamental C: Getting Closer To The Machine
Now available as a paperback and ebook from Amazon.
Also see the companion volume: Applying C
File handing is a difficult area because providing files and file access is the responsibility of the operating system and so cannot be really platform-independent. However, C does provide some standard file handling functions in the standard library and these are where you start, no matter what the machine or operating system.
The whole subject of file handling and file I/O is a very big one and there are many functions that are involved in format conversion and so on that we haven’t the space to cover. Once you have seen the basic and most commonly used functions, then the remainder are fairly easy to understand.
There is also a second set of file handling commands that are found on Linux and Unix systems – the file descriptor, which is covered in Applying C For The IoT With Linux.
The File Idea
If you are working with Unix or Linux there is an important principle concerning files that it is worth knowing – everything is a file. If you consider a file to be a stream of bytes, either on their way into the machine or on their way out of the machine, you can see that this idea covers many situations. You can consider a file stored on disk to be a Linux file, but you can also regard the stream of bytes generated by typing on a keyboard to be a file. As will become clear, even low-level sensors and devices can often be regarded as files. For this reason alone it is worth mastering C files at an early stage.
To be clear, the file handling provided by C isn’t part of the language. It is part of the C standard library of functions and this is mapped onto the native file handing of whatever operating system the program is being run under.
A file is a stream of bytes, but you can regard these bytes as character codes and hence treat the file as text, or you can regard them as raw bytes and treat the file as binary. If you have been following the “everything is a bit pattern” argument, you can see that there isn’t a lot of difference between text and binary files.
Before you can work with a file you have to open it. A file may exist somewhere before you open it or it may be created by opening it. Once a file is opened it can be worked on in a program and bytes can be read from it or written to it. Once you have finished working with a file you have to close it. If you don’t close a file then it might not be saved properly or the device dealing with it may not work correctly. In practice, if your program terminates normally files will be closed for you, but if it crashes you might not be so lucky. It is the general rule that files that you open are files that you should close and as soon as you can.
The function that is used to open a file is:
where filename is the name of the file and mode is how you want to do with the file. The fopen function is defined in stdio.h.
Mode is any of:
r open for read – returns NULL if file doesn’t exist
w open for write – if the file exists it is overwritten
a open for append – open file and add data to the end
r+ open for reading and writing – returns NULL if file doesn’t exist
w+ open for reading and writing – if the file exists it is overwritten
a+ open for reading and appending – if the file doesn’t exist it is created
All of these open the file in text mode if you add a b after the first letter then the file is open for binary processing. For example rb+ opens the file for reading and writing as a binary file.
In most cases there is no real difference between opening for binary or text mode. It is just a matter of what functions you use to read or write the file. However some implementations do make a distinction so if you want to write portable code open a file using the appropriate mode.
When you open a file you are returned a file pointer of type FILE *. If something went wrong then the file pointer is NULL. You use the file pointer to refer to the file in other operations.
For example to close the file you use
were fptr is the file pointer to the file you want to close.
The system defined three standard streams: stdin typically the keyboard, stdout typically the screen and stderr where error messages etc are sent.
|Last Updated ( Monday, 20 January 2020 )|