C programming tutorial on random access file handling gas mask drawing

A binary file is a file of any length that holds bytes with values in the range 0 to 255. These bytes have no other meaning unlike in a text file where a value of 13 means carriage return, 10 means line feed and 26 means end of file. Software reading text files have to deal with these other meanings.

Binary files a stream of bytes, and modern languages tend to work with streams rather than files. The important part is the data stream rather than where it came from. In C, you can think about the data either as files or streams. With random access, you can read or write to any part of the file or stream. With sequential access, you have to loop through the file or stream from the start like a big tape.

This example opens a binary file for writing and then writes a char * (string) into it. The FILE * variable is returned from the fopen() call. If this fails (the file might exist and be open or read only or there could be a fault with the filename), then it returns 0.

The fopen() command attempts to open the specified file. In this case, it’s test.txt in the same folder as the application. If the file includes a path, then all the backslashes must be doubled up. "c:\folder\test.txt" is incorrect; you must use "c:\\folder\\test.txt".

As the file mode is "wb," this code is writing to a binary file. The file is created if it doesn’t exist, and if it does, whatever was in it is deleted. If the call to fopen fails, perhaps because the file was open or the name contains invalid characters or an invalid path, fopen returns the value 0.

Although you could just check for ft being non-zero (success), this example has a FileSuccess() function to do this explicitly. On Windows, it outputs the success/failure of the call and the filename. It’s a little onerous if you are after performance, so you might limit this to debugging. On Windows, there is little overhead outputting text to the system debugger. fwrite(mytext,sizeof(char),strlen(mytext), ft) ;

The fwrite() calls outputs the specified text. The second and third parameters are the size of the characters and the length of the string. Both are defined as being size_t which is unsigned integer. The result of this call is to write count items of the specified size. Note that with binary files, even though you are writing a string (char *), it does not append any carriage return or line feed characters. If you want those, you must explicitly include them in the string.

The main reason for using binary files is the flexibility that allows you to read or write anywhere in the file. Text files only let you read or write sequentially. With the prevalence of inexpensive or free databases such as SQLite and MySQL, reduces the need to use random access on binary files. However, random access to file records is a little old fashioned but still useful. Examining an Example

There are two void functions: CreateFiles() and ShowRecord(int recnum). CreateFiles uses a char * buffer of size 1100 to hold a temporary string made up of the format string msg followed by n asterisks where n varies from 5 to 1004. Two FILE * are created both using wb filemode in the variables ftindex and ftdata. After creation, these are used to manipulate the files. The two files are

At this point, both the index file struct and the data file string can be written to their respective files. Although these are binary files, they are written sequentially. In theory, you could write records to a position beyond the current end of file, but it’s not a good technique to use and probably not at all portable.

The final part is to close both files. This ensures that the last part of the file is written to disk. During file writes, many of the writes don’t go directly to disk but are held in fixed-sized buffers. After a write fills the buffer, the entire contents of the buffer are written to disk.

After reading the record into memory, a null character \0 is appended to turn it into a proper c-string. Don’t forget it or you’ll get a crash. As before, fclose is called on both files. Although you won’t lose any data if you forget fclose (unlike with writes), you will have a memory leak.