There are two types of file: text and binary. The interpretation of text files differs between systems to match their internal ways of working with text, with special byte values for characters such as carriage return, line feed and end of file. Binary files are simply an array of bytes and are always written and read the same regardless of the type of system. The only issue that can occur is moving files between little endian and big endian systems where if a file has been specified using variables bigger than a byte (e.g. storing int values) the different endian systems will read and write the bytes of larger values in opposite order. This issue is avoided by always specifying the layout of files in bytes and where larger variables are stored specifying the byte order in which they are stored (i.e. if you always work with your file as a BYTE array you’re fine).
Binary files are therefore often more useful to use than text files (and can also be used to store text).
Headers
#include <stdio.h>
Opening A File
File mode specifiers
Binary files
“rb” – Opens the binary file for reading. This fails if the file does not exist or cannot be found.
“rb+” or “r+b” – Opens the binary file for both reading and writing. (The file must exist.)
“wb” – Opens the binary file as an empty file for writing. If the file exists, its contents are destroyed.
“wb+” or “w+b” – Opens the binary file as an empty file for both reading and writing. If the file exists, its contents are destroyed.
“ab” – Opens the file for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; this creates the file first if it doesn’t exist.
“ab+” or “a+b” – Opens the binary file for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.
Text Files
“r” – Opens the text file for reading. This fails if the file does not exist or cannot be found.
“r+” – Opens the text file for both reading and writing. (The file must exist.)
“w” – Opens the text file as an empty file for writing. If the file exists, its contents are destroyed.
“w+” – Opens the text file as an empty file for both reading and writing. If the file exists, its contents are destroyed.
“a” – Opens the text file for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; this creates the file first if it doesn’t exist.
“a+” – Opens the text file for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.
Read Write Binary File
//OPEN CONFIG FILE IN OUR APPLICAITONS DIRECTORY OR CREATE IT IF IT DOESN'T EXIST
FILE *file1;
unsigned char file_data[100];
const char *filename1 = "config.conf";
file1 = fopen(filename1, "rb");
if (file1)
{
//----- FILE EXISTS -----
fread(&file_data[0], sizeof(unsigned char), 100, file1);
printf("File opened, some byte values: %i %i %i %i\n", file_data[0], file_data[1], file_data[2], file_data[3]);
fclose(file1);
file1 = NULL;
}
else
{
//----- FILE NOT FOUND -----
printf("File not found\n");
//Write new file
file1 = fopen(filename1, "wb");
if (file1)
{
printf("Writing new file\n");
file_data[0] = 10;
file_data[1] = 11;
file_data[2] = 12;
file_data[3] = 13;
fwrite(&file_data[0], sizeof(unsigned char), 100, file1) ;
fclose(file1);
file1 = NULL;
}
}
Note that in this example the file will be read and written to the “current directory”, which if you don’t run the executable from the same directory as the executable file is in will not be in the directory where the executable is! To avoid this specify a fixed directory in the filename path, e.g. “/home/pi/my_directory/config.conf” (the directory must already exist or reading and writing will fail)
Write Text File
#include <fstream>
std::ofstream output_file("/home/pi/my_filename/"); //Will overwrite an existing file
//std::ofstream output_file("/home/pi/my_filename/", std::ios_base::app); //Will append to an existing file
output_file << "blah blah";
output_file.close(); //(Not strictly necessary as it will get closed when output_file goes out of scope)
Move File Pointer
fseek/fsetpos – move a file pointer to a new position in a file
Read File Pointer
ftell/fgetpos – where is the file pointer currently located?
Does File Exist
#include <sys/stat.h>
#include <fcntl.h>
//----- DOES FILE EXIST -----
struct stat sb;
int Result = stat("/etc/network/interfaces", &sb);
if ((Result != 0) || (sb.st_mode & S_IFDIR))
{
//FILE DOES NOT EXIST
}
Get Current Position In file
long int file_index = ftell(file1);
Flush File (Write any unwritten data to the file)
fflush(file1);
Get File Size
There isn’t a dedicated function so you have to open it and seek to the end!
//----- GET THE FILE SIZE -----
ifstream file1( "example.txt", ios::binary | ios::ate);
int filesize = file1.tellg();
file1.close();