Objects and binary files( Объекты и двоичные файлы )

Object and binary file

Stroing data in binary file
Binary file မ်ားသည္ ပိုမို၍ တိက် က်စ္လစ္မွဳ႕ရွိျပီး တစ္ခ်ိဳ႕ေသာအေျခအေနမ်ိဳးတြင္ operate ျပဳလုပ္ရန္ပိုမို၍ အဆင္ေျပလြယ္ကူေစသည္။
Binary file အား open ျပဳလုပ္ရန္အတြက္ access_mode ျဖစ္ေသာ ios::binary အား မျဖစ္မေန အသံုးျပဳရမည္။ ( တစ္ခ်ိဳ႕ေသာ C++ compiler မ်ားတြင္ ios::bin )
Output file အတြက္ object တစ္ခုအားတည္ေဆာက္ရန္အတြက္ ေအာက္ေဖာ္ျပပါအတိုင္းျပဳလုပ္ရမည္။
ofstream out_fil(“Outfil.dat”,ios::out | ios::binary);
if(!out_fil) { cerr<<”Error:Outfil.dat”<<endl;
                   exit(1);
               }
တည္ရွိျပီးသား binary_file တစ္ခုအား read ျပဳလုပ္လိုလွ်င္ ေအာက္ေဖာ္ျပပါအတိုင္း object တည္ေဆာက္ရမည္။
Ifstream in_fil(“Infil.dat”,ios::in | ios::binary);
if(!in_fil) {   cerr<<”Error:Infil.dat”<<endl;
                  exit(2);
              }

သို႕ေသာ္ တကယ့္လက္ေတြ႕တြင္ binary_file မ်ားအား operate ျပဳလုပ္ရန္အတြက္ တစ္ျခား ေသာ လုပ္ေဆာင္ခ်က္ အနည္းအား မိမိျပဳလုပ္လိုသည့္ ပုစၦာေပၚမူတည္၍ အနည္းငယ္ ထပ္မံ ေပါင္းထည့္ရန္ လိုအပ္ေပသည္။

Example. Write double type data into binary file.

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <conio.h>
using namespace std;
class bin_outstream: public ofstream
{public:
 bin_outstream(const char *fn):
ofstream(fn, ios::out | ios::binary) {}
 void writeOurDate(const void*, int);
 ofstream &operator<<(double d)
   { writeOurDate(&d, sizeof(d));
           return *this;
   }
};
int _tmain(int argc, _TCHAR* argv[])
{setlocale(LC_ALL, "Russian");     // подключение русификатора
 bin_outstream bin_out("B_out.dat");
 if (!bin_out)
   { cerr << "Unable to write to B_out.dat"
          << endl;
           exit(1);
   }
 double d = 5.252;
 bin_out << d;
 bin_out << d*d;
 d = 5.2E-5;
 bin_out << d;
 _getch();     
 return 0;
}
void bin_outstream ::writeOurDate(const void *Ptr, int len)
{ if (!Ptr) return;
  if (len <= 0) return;
  write((char*)Ptr, len);
}


Example. Read double type value from binary file.

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <conio.h>
using namespace std;
class bin_instream: public ifstream
{public:
  bin_instream(const char *fn):
        ifstream(fn, ios::in | ios::binary)  {}
  void readOurDate(void*, int);
  bin_instream &operator>>(double &d)
   { readOurDate(&d, sizeof(d));
            return *this;
   }
};
int _tmain(int argc, _TCHAR* argv[])
{setlocale(LC_ALL, "Russian");       // подключение русификатора
 bin_instream bin_in("B_in.dat");
 if (!bin_in) { cerr << "Unable to open B_in.dat"
                     << endl;
                       exit(1);
                     }
 double d;
 long count = 0;
 bin_in >> d;
 while (!bin_in.eof())  
   { cout << ++count << ":"<< d << endl;
           bin_in >> d;
   }
 _getch();     
 return 0;
}
void bin_instream:: readOurDate(void *p, int len)
{ if (!p)   return;
  if (len <= 0)   return;
  read((char*)p, len);
}


Random access to element of binary file

File pointer
File တိုင္းသည္ write pointer ႏွင့္ read pointer ဟူေသာ pointer မ်ားႏွင့္ အျမဲဆက္စပ္ အလုပ္လုပ္ေနသည္ ျဖစ္သည္။ တစ္နည္းအားျဖင့္ ၎အား file_pointer (သို႕) current_position ဟုေခၚဆိုသည္။
File ၏ element မ်ားအား sequential access ျပဳလုပ္ပါက file_pointer သည္ အလိုအေလ်ာက္ တစ္ဆင့္ျခင္းေရႊ႕ေျပာင္းသြားမည္ျဖစ္သည္။ သို႕ေသာ္ တစ္ခါတစ္ရံတြင္ file_pointer မ်ား၏ အေျခအေနမ်ားအား ထိန္းခ်ဳပ္ရန္လိုအပ္ေပသည္။ ထိုသို႕ ထိန္းခ်ဳပ္အသံုးျပဳရန္အတြက္ ေအာက္ေဖာ္ျပပါ function မ်ားအား အသံုးျပဳနိုင္သည္။
  • seekg()         -set the current read pointer
  •  tallg()            -check the current read pointer
  •  seekp()         -set the current write pointer
  •  tellp()           -check the current write pointer


Accessing elements to the binary file
အထက္တြင္ ေဖာ္ျပခဲ့ေသာ file_pointer မ်ား၏ အက်ိဳးေက်းဇူးေၾကာင့္ binary_file မ်ားတြင္ element မ်ားအား access ျပဳလုပ္ရန္အတြက္ istream class တြင္ ရွိေသာ overload function_elements မ်ားအားျဖင့္ implement ျပဳလုပ္နိုင္သည္ျဖစ္သည္။

istream &seekg(streampos)           or
istream &seekg(streamoff,ios::seek_dir);

streampos ႏွင့္ streamoff မ်ား၏ data_type သည္ long နွင့္တူညီသည္။ သို႕ေသာ္ compiler အမ်ိဳးမ်ိဳးရွိေသာေၾကာင့္ long data_type ဟုအတိက်မသတ္မွတ္သင့္ေပ။ ထို႕ေၾကာင့္ ၎တို႕အား ေအာက္ပါအတိုင္း define ျပဳလုပ္နိုင္သည္။

tpyedef long streampos;
typedef long streamoff;

seekg function ၏ ပထမေနရာသည္ သတ္မွတ္ထားေသာ bite ပမာဏအတိုင္း input stream ၏ ေနရာအား ေဖာ္ျပျခင္းျဖစ္သည္။ ဒုတိယေနရာသည္ ေအာက္တြင္ေဖာ္ျပထားေသာ iso::seek_dir ၏ သံုးခုအနက္ တစ္ခုခုျဖင့္ offset ျပဳလုပ္ရမည္ျဖစ္သည္။

Constant
Value
Definitation
beg
0
Поиск от начала файла
cur
1
Поиск от текущей позиции файла
end
2
Поиск от конца файла

Output_file stream အတြက္ internal file_pointer stream အား ေနရာခ်ထားရန္အတြက္ ostream class ၏ ေအာက္တြင္ရွိေသာ outfile stream overload_function အားအသံုးျပဳရမည္ျဖစ္သည္။
Ostream &seekp(streampos);
Ostream &seekp(streamoff,ios::seek_dir);

Example. အျပည့္ကိန္းမ်ားပါ၀င္ေသာ binary-file တစ္ခုတြင္ ထိုဖိုင္၏ max_value ေနရာ ၌ စုံကိန္းမ်ား၏စုစုေပါင္းရလဒ္ ႏွင့္ အစားထိုးလဲလွယ္ေပးရန္ ။

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <time.h>
#include <conio.h>

using namespace std;

class bin_stream: public fstream
{public:       
  bin_stream(const char *fn):
   fstream(fn, ios::out | ios::in | ios::binary){}
  void doneOurDate(const void*, int, int);
  bin_stream &operator<<(int d)
    { doneOurDate(&d, sizeof(d),0);
            return *this;
          }
  bin_stream &operator>>(int &d)
    { doneOurDate(&d, sizeof(d),1);
            return *this;
          }
};

class bin_outstream: public ofstream
{public:
  bin_outstream(const char *fn):
   ofstream(fn, ios::out | ios::binary) {}
  void writeOurDate(const void*, int);
  ofstream &operator<<(int d)
   { writeOurDate(&d, sizeof(d));
           return *this;
   }
};

int _tmain(int argc, _TCHAR* argv[])
{setlocale(LC_ALL, "Russian");       // подключение
// русификатора
 int i, d, max, i_max=0, sum_even = 0;
 time_t t;
 srand((int)time(&t));
 bin_outstream bin_out("Bin.dat"); // создание
 //файла
 if (!bin_out)
   { cerr << "Unable to write to Bin.dat" << endl;
           exit(1);
   }
 for (i = 0; i < 10; i++)
    { d = rand() % 100;
            bin_out << d;
            if (d % 2 == 0) sum_even += d;
          }
 cout<<endl;
 cout<<sum_even<<endl;
 bin_out.close();
   
 bin_stream bin("Bin.dat"); // обработка файла
 if (!bin)
  { cerr << "Unable to write to Bin.dat" << endl;
          exit(1);
  }
 bin >> max;
 i_max = 0;
 for (i = 1; i < 10; i++)
    { bin >> d;
            if (d > max) { max = d; i_max = i; }
          }
 cout<<endl;
 bin.seekp(sizeof(int) * i_max, ios::beg);
 bin << sum_even;
 bin.seekp(0, ios::beg);
 for (i = 0; i < 10; i++)
    { bin >> d;
            cout <<d <<' ';
          }
 bin.close();
 _getch();     
 return 0;
}

void bin_stream:: doneOurDate(const void *Ptr, int len, int sign)
{ if (!Ptr)   return;   
if (len <= 0)   return;   
if (sign==0) write((char*)Ptr, len);
          else  read((char*)Ptr, len);
}


void bin_outstream :: writeOurDate(const void *Ptr, int len)
{ if (!Ptr) return;
  if (len <= 0) return;
  write((char*)Ptr, len);
}

translated by zmk@miet51




No comments:

Post a Comment