C + + Learning 49 read and write to binary files

Source: Internet
Author: User
Tags function prototype

Binary files do not hold data in ASCII code, it transfers the in-memory data storage form to disk files without conversion, so it is also called an image file of memory data. Because the information in a file is not character data, it is a binary form of information in bytes, so it is also called a byte file.

The operation of the binary file will also need to open the file, after the end of the file to close. The ios::binary is specified to be transmitted and stored in binary form when it is opened. Binary files can be both input and output files, in addition to being input or output files. This is a different place from the ASCII file.

Read and write binary files with member functions

The read and write of binary files are mainly implemented by the member functions of the IStream class read and write. The prototypes of these two member functions are
istream& Read (char *buffer,int len);
ostream& Write (const char * buffer,int len);
The character pointer buffer points to a piece of storage space in memory. Len is the number of bytes read and written. The method is called:
A. Write (p1,50);
B. Read (p2,30);

A in the first line above is the output file stream object, and the Write function writes the 50-byte contents of the character pointer P1 the address given to the disk file without conversion. In the second row, B is the input file stream object, and the Read function reads 30 bytes (or end of EOF) from the disk file associated with B, and is stored in a space referred to by the character pointer P2.

[Example 13.14] A batch of data is stored in a binary form in a disk file.

#include <fstream>using namespacestd;structstudent{Charname[ -]; intnum; intAge ; Charsex;};intMain () {student stud[3]={"Li",1001, -,'F'," Fun",1002, +,'m',"Wang",1004, -,'F'}; Ofstream outfile ("Stud.dat", ios::binary); if(!outfile) {Cerr<<"Open error!"<<Endl; Abort ();//Exit Program   }    for(intI=0;i<3; i++) Outfile.write (Char*) &stud[i],sizeof(Stud[i]));   Outfile.close (); return 0;}

Using the member function write to Stud.dat output data, from the previous write function prototype can be seen: the 1th parameter is a pointer to the char type constant variable buffer, the reason is declared with Const because it is not allowed to change the value of its point to the data by the pointer. Formal parameters require that the corresponding argument is the first address of a character pointer or string. Now you want to output an element of the struct array (containing 4 members) to the disk file Stud.dat one time. &tud[i] is the first address of the first element of the struct array, but this is a pointer to the struct, which does not match the parameter type. So use (char *) to cast it to a character pointer. The 2nd parameter is the number of bytes that specify the output at a time. The value of sizeof (Stud[i]) is the number of bytes of an element in the struct array. Once the write function is called, an element of the struct array starting from &tud[i] is output to the disk file, and 3 elements of the array of 3 loop output structures are executed.

You can actually output the elements of the struct array one at a time, changing the two lines of the For loop to the following line:
Outfile.write ((char*) &stud[0],sizeof (stud));
Once the Write function is executed, all data for the struct array is output.

The Abort function is the exit program, the same as the Exit function.

It can be seen that this method can be used to output a batch of data at a high efficiency. You do not have to add a space between the output data, and you do not have to add a carriage return after one output. The data is later read from the file is not by the space as the interval of data, but by the number of bytes to control.

Example 13.15] reads the data that was stored in the disk file in binary form into memory and displays it on the display.

#include <fstream>using namespacestd;structstudent{stringname; intnum; intAge ; Charsex;};intMain () {student stud[3]; inti; Ifstream infile ("Stud.dat", ios::binary); if(!infile) {Cerr<<"Open error!"<<Endl;   Abort (); }    for(i=0;i<3; i++) Infile.read (Char*) &stud[i],sizeof(Stud[i]));   Infile.close ();  for(i=0;i<3; i++) {cout<<"NO."<<i+1<<Endl; cout<<"Name:"<<stud[i].name<<Endl; cout<<"Num:"<<stud[i].num<<Endl;; cout<<"Age :"<<stud[i].age<<Endl; cout<<"Sex:"<<stud[i].sex<<endl<<Endl; }   return 0;}

Think about whether you can read all the data in a file at once, such as:
Infile.read ((char*) &stud[0],sizeof (stud));
The answer is yes, read the specified number of bytes into memory and store it in the storage space starting at address &tud[0]. Note that the format of the data being read is matched to the format of the space in which it is stored. Because the data in the disk file is derived from an in-memory struct array element, it retains the data format of the struct element. Now read into the memory and store it in the same struct array, which is bound to match. If you put it in an array of integers, it does not match and an error occurs.

Flow member functions related to file pointers

There is a file pointer in the disk file that indicates where the current read and write should be made. The pointer moves backwards by one byte each time the input is read into a section. When outputting one byte per output, the pointer moves backwards by one byte, and as the bytes in the output file continue to increase, the pointer moves back. For binary files, the pointer is allowed to be controlled so that it is moved to the desired location as the user intends to read and write at that location. The file stream provides some member functions about the file pointer. For ease of reference, they are summarized in table 13.7 and are described as necessary.

Table 13.7 file stream member functions related to file pointers
member functions function
Gcount () Returns the number of bytes read in the last input
TELLG () Returns the current position of the input file pointer
SEEKG (location in file) Moves the pointer in the input file to the specified location
SEEKG (displacement amount, reference position) Move several bytes based on a reference position
TELLP () Returns the current position of the output file pointer
SEEKP (location in file) Moves the pointer in the output file to the specified location
SEEKP (displacement amount, reference position) Move several bytes based on a reference position


A few notes:
1) The first or last letter of these function names is either a G or P. With G is the function for the input (G is the first letter of Get, with G as the identifier of the input, easy to understand and remember), with P is the function for the output (P is the first letter of put, with p as the output of the identity). For example, there are two tell functions, tellg for input files, and TELLP for output files. Similarly, SEEKG is used for input files and SEEKP for output files. The above function is known by the name, a look will understand, do not have to rote.

If it is a file that can be both input and output, use either SEEKG or SEEKP.

2) The position in file and displacement amount in the function parameter have been specified as long integers, in bytes. "Reference location" can be one of three of the following:
Ios::beg the beginning of the file (beg is the abbreviation for begin), which is the default value.
Ios::cur the current position of the pointer (cur is the abbreviation for the present).
Ios::end the end of the file.
They are enumerated constants that are defined in the iOS class. Examples are as follows:
INFILE.SEEKG (100); The pointer in the input file moves forward to the byte position
INFILE.SEEKG ( -50,ios::cur); The pointer in the input file moves bytes from the current position
OUTFILE.SEEKP ( -75,ios::end); The pointer in the output file moves bytes from the end of the file

Random Access binary data files

In general, read and write are sequential, that is, read and write bytes by byte. However, for binary data files, you can use the member functions above to move the pointer, randomly access data in any location of the file, and modify the contents of the file.

[Example 13.16] There is a student's data that requires:

    • Store them in a disk file;
    • Read the 3, 5 student data in the disk file into the program and display it;
    • Change the data of the first student back to the original location in the disk file.
    • Reads the modified student's data from the disk file and displays it.


To achieve the above requirements, you need to solve a problem:

      • Because the same disk file requires frequent input and output in the program, you can specify how the file works as an input-output file, which is ios::in|ios::out|ios::binary.
      • Correctly calculate the position of the pointer on each access, that is, the correct use of the SEEKG or SEEKP function.
      • Rewrite (update) the data in the file correctly.
#include <fstream>using namespacestd;structstudent{intnum; Charname[ -]; floatscore;};intMain () {student stud[5]={1001,"Li", -,1002," Fun",97.5,1004,"Wang", Wu,1006,"Tan",76.5,1010,"Ling", the}; FStream Iofile ("Stud.dat"Ios::inch|ios:: out|ios::binary); //defines the input-output binary file stream object with the FStream class Iofile   if(!iofile) {Cerr<<"Open error!"<<Endl;   Abort (); }    for(intI=0;i<5; i++)//output A student's data to a disk fileIofile.write ((Char*) &stud[i],sizeof(Stud[i])); Student stud1[5];//used to store data read from a disk file    for(intI=0;i<5; i=i+2) {IOFILE.SEEKG (i*sizeof(Stud[i]), Ios::beg);//located at the beginning of section, 2, 4 student data//read a student's data, stored in stud1[0],stud[1] and stud[2]Iofile.read ((Char*) &stud1[i/2],sizeof(stud1[0])); //output STUD1[0],STUD[1] and stud[2] values for each membercout<<stud1[i/2].num<<" "<<stud1[i/2].name<<" "<<stud1[i/2].score<<Endl; } cout<<Endl; stud[2].num=1012;//Modify the data for the first student (serial number)strcpy (stud[2].name,"Wu"); stud[2].score= -; IOFILE.SEEKP (2*sizeof(stud[0]), Ios::beg);//position at the beginning of the first student dataIofile.write ((Char*) &stud[2],sizeof(stud[2]));//Update the first student dataIOFILE.SEEKG (0, Ios::beg);//Relocate to the beginning of a file    for(intI=0;i<5; i++) {Iofile.read (Char*) &stud[i],sizeof(Stud[i]));//read a student's datacout<<stud[i].num<<" "<<stud[i].name<<" "<<stud[i].score<<Endl;   } iofile.close (); return 0;}

This program can also be the disk file Stud.dat successively defined as output file and input file, close the file after the first output, and then open it by the input mode, then close it, then press the output mode to open it, then close, then press the input mode to open it, and then close. Obviously this is very cumbersome and inconvenient. A binary file that designates it as an input-output type in the program. This allows you to not only add new or read data to a file, but also modify (update) the data. With these features, you can achieve more complex input and output tasks.

Note that you cannot define binary stream objects for input and output with the Ifstream or Ofstream class, and you should use the FStream class.

C + + Learning 49 read and write to binary files

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.