C++ Read() And Write() For Binary File Operations

C++ Read() And Write() For Binary File Operations

Before introducing the specific implementation methods, let’s first explain the benefits of reading and writing files in binary format compared to text format.For example, if we want to create a student management program, an important task is to record students’ IDs, names, ages, and other information. This means we need a class to represent a student, as shown below:

class CStudent
{
char szName[20];  // Assume student name does not exceed 19 characters, ending with '\0'
char szId[10];  // Assume ID is 9 digits, ending with '\0'
int age;  // Age
};

In previous chapters, we learned how to read and write files in text format. If we store student information using this method, the final file might look like this:Micheal Jackson 110923412 17Tom Hanks 110923413 18……This method of storing student information not only wastes space but also makes it difficult to find specific student information later (search efficiency is low) because the number of bytes occupied by each student’s information is different.In this case, storing student information in binary format is a very good choice because it allows us to directly write the CStudent object to the file, meaning each student’s information only occupies sizeof(CStudent) bytes.It is worth mentioning that to implement binary file reading and writing, the << and >> operators are no longer applicable; instead, we need to use the read() and write() member methods provided by the C++ standard library. The read() method is used to read data from a file in binary format, while the write() method is used to write data to a file in binary format.

C++ ostream::write() Method for Writing Files

The write() member method of ofstream and fstream actually inherits from the ostream class, and its function is to write count bytes of content pointed to by the memory buffer to a file. The basic format is as follows:ostream & write(char* buffer, int count);Here, buffer specifies the starting position of the binary data to be written to the file; count specifies the number of bytes to be written.

This means that this method can be called by the cout object of the ostream class, which is commonly used to output strings to the screen. It can also be called by ofstream or fstream objects to write a specified number of binary data to a file.

Additionally, this method returns a reference to the object that called the function. For example, the return value of obj.write() is a reference to the obj object.It is important to note that the write() member method writes several bytes to the file, but when calling the write() function, we do not specify the exact position where these bytes are written in the file. In fact, the write() method writes binary data starting from the position pointed to by the file write pointer. The file write pointer is a variable maintained internally by the ofstream or fstream object. When the file is first opened, the file write pointer points to the beginning of the file (if opened in ios::app mode, it points to the end of the file). When we write n bytes using the write() method, the write pointer moves forward by n bytes.The following program demonstrates how to write student information to a file in binary format:

#include <iostream>
#include <fstream>
using namespace std;
class CStudent
{
public:
char szName[20];
int age;
};
int main()
{
CStudent s;
ofstream outFile("students.dat", ios::out | ios::binary);
while (cin >> s.szName >> s.age)
outFile.write((char*)&s, sizeof(s));
outFile.close();
return 0;
}

Input:Tom 60↙Jack 80↙Jane 40↙^Z↙Where,<span>↙</span>indicates a newline, and ^Z indicates the end of input using<span>Ctrl+Z</span>key combination.After executing the program, a students.dat file will be automatically generated, which contains 72 bytes of data. If you open this file with “Notepad”, you might see some garbled text:Tom 烫烫烫烫烫烫烫烫< Jack 烫烫烫烫烫烫烫蘌 Jane 烫烫烫烫烫烫烫?It is worth mentioning that in line 13 of the program, the file is opened in ios::out | ios::binary mode, which is very necessary on Windows platforms; otherwise, errors may occur.Moreover, line 15 writes the s object to the file. The address of s is the address of the memory buffer to be written to the file, but &s is not of type char *, so type casting is necessary. In line 16, the file must be closed after use; otherwise, the contents of the file may be incomplete after the program ends.

C++ istream::read() Method for Reading Files

The read() method of ifstream and fstream actually inherits from the istream class, and its function is exactly the opposite of the write() method, i.e., it reads count bytes of data from the file. The syntax format of this method is as follows:istream & read(char* buffer, int count);Here, buffer specifies the starting position for reading bytes, and count specifies the number of bytes to read. Similarly, this method also returns a reference to the object that called this method.Like the write() method, the read() method starts reading several bytes from the position pointed to by the file read pointer. The file read pointer can be understood as a variable maintained internally by the ifstream or fstream object. When the file is first opened, the file read pointer points to the beginning of the file (if opened in ios::app mode, it points to the end of the file). When using the read() method to read n bytes, the read pointer moves forward by n bytes. Therefore, after opening a file, continuously calling the read() method will allow us to read the entire content of the file.By executing the example program of the write() method, we have stored the information of 3 students in the students.dat file. The following program demonstrates how to use the read() method to read them back:

#include <iostream>
#include <fstream>
using namespace std;
class CStudent
{
public:
char szName[20];
int age;
};
int main()
{
CStudent s;
ifstream inFile("students.dat",ios::in|ios::binary); // Open in binary read mode
if(!inFile) {
cout << "error" <<endl;
return 0;
}
while(inFile.read((char *)&s, sizeof(s))) { // Read until the end of the file
cout << s.szName << " " << s.age << endl;
}
inFile.close();
return 0;
}

The output of the program is:Tom 60Jack 80Jane 40Note that in line 18 of the program, the read() method is directly used as the condition for the while loop, which means the read() method will keep reading until the end of the file, and the while loop will terminate only after all bytes have been read.

Additionally, while using the read() method, if you want to know how many bytes were successfully read (it may not read count bytes when reaching the end of the file), you can immediately call the gcount() member method of the file stream object after the read() method executes; its return value is the number of bytes successfully read by the last read() method. Interested readers can try this themselves; we will not demonstrate it here.

The editor has compiled a set ofC languagelearning materials. If you need them, please private message@C语言学习联盟and replyto receive the materials. Everyone is welcome to follow, and I will share related technical articles in a timely manner. Your attention and likes are very important to me. Thank you all for clicking on the follow button!* Disclaimer:This article is compiled from the internet, and the copyright belongs to the original author. If there is any incorrect information or infringement of rights, please contact us for deletion or authorization matters.

Leave a Comment