Read and write C ++ binaries

We first look Why use binary files, which it has benefits than text files.

Text information stored not only a waste of space, and not easy retrieval. For example, a school management program needs to record all student number, name, age information, and students can find information by name. Program can be used to represent a class of students:

class CStudent
{
    char szName[20];  //假设学生姓名不超过19个字符,以 '\0' 结尾
    char szId[l0];  //假设学号为9位,以 '\0' 结尾
    int age;  //年龄
};
如果用文

The information in this document is stored students' files may look like the following:
Micheal Jackson 110 923 412 17
Tom Hanks 110 923 413 18

This is not only a waste of storage space, and look inefficient. Because of the different number of bytes of information for each student occupied, even if the student information in the file is sorted by name, use the program to find still no good way according to the name, can only start to finish in a file search for.

If you put all the student information is read into memory and then look for the sort, of course, the speed will be fast, but if a huge number of students, the students put all information is read into memory may be unrealistic.

You can use a binary way to store student information, that CStudent object into the file directly. In this document, the information for each student occupies sizeof (CStudent) bytes. When an object file is written generally referred to as "record." In the present embodiment, each student corresponds to a record. The student record files can be sorted by name, then use a binary search would be very efficient.

Reading and writing binary file may not be similar to the aforementioned cin, cout method of reading and writing data from the stream. Then you can call read ifstream class member functions and classes fstream to read data from a file, call the member function write ofstream and fstream write data to the file.
With ostream :: write member function to write the file
ofstream and fstream actually write member functions inherited from ostream class prototype is as follows:
ostream & write (char * Buffer, int COUNT);

The member function to the contents of memory buffer pointed to count bytes written to the file, the return value is a reference to a function is a function, such as obj.write (...) is a reference to the return value of obj.

write member function of a number of bytes written to the file, but did not specify what position this number of bytes to be written to the file when you call the write function. So, write this function in the end where the number of bytes written during execution of it? The answer is to start writing from a file write position pointer.

File write pointer is a variable ofstream or fstream internal object maintenance. Just when the file is opened, the file pointer to the beginning of the write file (if opened to ios :: app embodiment, the point end of the file), n bytes written by the write function, the position of the write pointer is moved rearwardly n words section.

The following program from the keyboard several student's name and age (when entered in a single line press Ctrl + Z key and then press Enter to complete the entry. Assuming that there are no spaces in the student's name), and binary file format storage, become a student record file students.dat.

Examples of student records stored in binary files:

#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↙

Students.dat is formed of 72 bytes, use the "Notepad" program opens garbled:
Tom hot hot hot hot hot hot hot hot hot hot hot hot hot Jack hot hot? Jane hot hot hot hot hot hot hot?

The first 13 rows of the specified file open mode is ios :: out | ios :: binary, that is, in binary write mode is turned on. In the Windows platform, opened in binary mode is necessary, or else may be wrong, the reason will be "open text files and binary difference between the way open" in a described.

15 s about to write the object files. s address is the address to write to the memory buffer file. But instead of type char * & s, so to be cast.

Line 16, the file must be closed after use, otherwise the contents of the file after the end of the program may be incomplete.
With istream :: read member function read files
ifstream and fstream the read member function is actually inherited from the istream class prototype is as follows:
istream & read (char * Buffer, int COUNT);

The member function reads count bytes from the file contents stored in the buffer pointed to by the buffer memory, the return value is a reference to a function is a function.

If you want to know the total number of bytes successfully read (when read end of the file may not be able to read count bytes), you can call the member function immediately gcount file stream object after the read function is executed, the return value is the most recent function is executed, the number of bytes read once read. gcount istream class member function, the following prototype:
int gcount ();

member function read the read pointer to read from the file starting position a number of bytes. File read pointer is a variable or fstream ifstream internal object maintenance. Just when the file open, file read pointer to the beginning of the file (if opened to ios :: app embodiment, the point end of the file), n bytes read by the read function, the position of the read pointer is moved rearwardly n words section. Therefore, after successive calls to open a file read function, you will be able to read out the contents of the entire document.

The following program will be created in front of the contents of the student record file students.dat read and displayed.

#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); //二进制读方式打开
    if(!inFile) {
        cout << "error" <<endl;
        return 0;
    }
    while(inFile.read((char *)&s, sizeof(s))) { //一直读到文件结束
        int readedBytes = inFile.gcount(); //看刚才读了多少字节
        cout << s.szName << " " << s.age << endl;   
    }
    inFile.close();
    return 0;
}

The output of the program are:
Tom 60
Jack 80
Jane 40

Method whether line 18, and determines if the file has been read while (cin >> n) Similarly, since the final analysis istream class overloads the cast bool operator.

Line 19 is to demonstrate the use of gcount function, remove that line has no effect on the results of running the program.

Questions: About two programs students.dat, if the definition of CStudent szName class is not "char szName [20]" but "string szName", if you can? why?
A file stream classes put and get member function to read and write the file
can get member function ifstream and fstream classes (class inherits from istream) reads one byte from the file, can also be used and put ofstream fstream class member functions (inherited from ostream class) writes a byte to the file once.

Example: mycopy write a program, file replication functions. Usage in the "Command Prompt" window, enter:
mycopy source file name of the target file name

You will be able to copy the source file to the target file. For example:
mycopy src.dat dest.dat

Coming src.dat copied to dest.dat. If dest.dat already exists, the original file will be overwritten.

The basic idea of ​​solving each time a byte is read from the source file, and then written to the destination file. Procedures are as follows:

#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
    if (argc != 3) {
        cout << "File name missing!" << endl;
        return 0;
    }
    ifstream inFile(argv[l], ios::binary | ios::in);  //以二进制读模式打开文件
    if (!inFile) {
        cout << "Source file open error." << endl;
        return 0;
    }
    ofstream outFile(argv[2], ios::binary | ios::out);  //以二进制写模式打开文件
    if (!outFile) {
        cout << "New file open error." << endl;
        inFile.close();  //打开的文件一定要关闭
        return 0;
    }
    char c;
    while (inFile.get(c))  //每次读取一个字符
        outFile.put(c);  //每次写入一个字符
    outFile.close();
    inFile.close();
    return 0;
}

Files are stored on disk, disk access speed is far below the memory. If every time a byte read or write a byte have access to the disk, then the file will be slow read and write speeds could not be tolerated. Accordingly, the operating system upon receiving a request to read a file, even as long as a byte is read, the data will be the one (typically at least 512 bytes, as a sector of the disk 512 B) are read into an operation the system self-managed buffer memory, when the next byte to be read, there is no need to access the disk, read directly from the buffer it.

When the operating system receives a request to write a file, the data is first written to be saved in a memory buffer, the buffer is full, etc., and then all the contents of the buffer is written to disk. Close the file operation will ensure that the data in the memory buffer is written to disk.

Nevertheless, when you want to continuously read and write files, like mycopy program as a byte by byte read and write, not as good as the first area of ​​memory read and write faster. Every read and write bytes is preferably an integer multiple of 512.

Guess you like

Origin blog.csdn.net/u013693952/article/details/93194350