C++ 输入输出流之文件操作和文件流

来源:互联网 发布:电子cad设计软件 编辑:程序博客网 时间:2024/06/05 13:22

参考文章:http://blog.sina.com.cn/s/blog_95b655e001013te4.html

1. 根据文件中数据的组织形式,文件分为:

  • ASCII文件(文本文件或者字符文件):它的每个字节存放一个ASCII代码,代表一个字符(一一对应),易于阅读,方便显示和打印。
    • 例如:43,00000100 00000011
  • 二进制文件(内部格式文件或字符文件):是把内存中的数据按照其在存储中的形式原样输出到磁盘上存放,节省空间,输入输出快,效率高。
    • 例如:43,00101011
  • 备注:对于字符信息,在内存中以ASCII代码形式存放的,无论以ASCII文件输出还是用二进制文件输出,其数据形式都一样。

2. 文件流类与文件流对象

  • ifstream:支持从磁盘文件的输入
  • ofstream:支持从磁盘文件的输出
  • fstream:支持从磁盘文件的输入输出。

3. 文件的打开与关闭

  • 打开一个输出文件:
    • 定义一个输出流对象outfile,并使对象与文件建立关系
    • ofstream outfile; 
    • outfile.open(磁盘文件名,输入输出方式); //或者ofstream outfile("f1.dat", ios::out);
    • 打开操作失败,open函数的返回值为0。
  • 关闭磁盘文件:
    • outfile.close();
    • 关闭实际上是结出该磁盘文件与文件流的关联,文件流不能对文件进行输入输出。
  • 文件输入输出方式设置值
    • ios::app:   以追加的方式打开文件 
    • ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
    • ios::binary:  以二进制方式打开文件,缺省的方式是ASCII方式(文本方式)。
    • ios::in:    文件以输入方式打开(文件=>程序) 
    • ios::out:   文件以输出方式打开(默认)(程序=>文件),如果有次名字的文件,清除其内容
    • ios::nocreate: 不创建新文件,只打开已有文件,如果文件不存在打开失败。 
    • ios::noreplace:不更新原有文件,如果文件不存在则建立新文件,如果文件存在,打开失败。
    • ios::trunc:  如果文件存在,删除其全部数据;如果文件不存在,创建文件。
      • 如已指定了ios::out,而未指定ios:app,ios::ate,ios::in,默认此项
    • 位或运算符号"|"进行组合
      • ios::in|ios:out:已输入输出方式打开文件,文件可读可写
      • ios::out|ios::binary:以二进制方式打开一个输出文件
      • ios::in|ios::binary:以二进制方式打开一个输入文件
4. 对ASCII文件的操作
  • 举例:向磁盘文件存入一个数(outfile跟cout具备相同的功能,只是作用对象不一样)
    • ofstream outfile("filename.txt", ios::out);
    • if (!outfile)                  // 打开成功,outfile返回非0;打开失败,outfile返回0
    •     cerr<< "open error" << endl; 
    •     exit(1); 
    • }
    • outfile << 123 << " ";  // 将"123 "写入文件
    • outfile.close();
  • 举例:从磁盘文件中读入一个数据 (infile与cin具备相同的功能,只是作用对象不一样)
    • ifstream infile("filename.txt", ios::in|in::nocreate);    // 默认ios::in
    • if (!infile)                  // 打开成功,返回非0;打开失败,返回0
    •     cerr << "open error" << endl; 
    •     exit(1); 
    • }
    • int number;
    • infile >> number;
    • infile.close();
5. 对二进制文件的操作
  • 使用成员函数read和write读取二进制文件
    • istream &read(char *buffer, int len);
    • ostream& write(constchar *buffer, int len)
    • 举例:将一批数据存入磁盘文件
      • student stu[2] = {{"Li", 1001, 18}, {"Wang", 1002, 19}};
      • ofstream outfile("stu.dat", ios::binary);
      • if (!outfile)
      • {
      •     cerr << "open error" << endl;
      •     abort();
      • }
      • for (int i = 0; i < 2; i++)
      •     outfile.write((char *)&stu[i],sizeof(stu[i]));  // 取stu[i]的首地址,并强制转换为(char *)
      • outfile.close();
    • 举例:将一批数据从磁盘文件中读入内存
      • student stu[2];
      • ifstream infile("stu.dat", ios::binary);
      • if (!infile)
      • {
      •     cerr << "open error" << endl;
      •     abort();
      • }
      • for (int i = 0; i < 2; i++)
      •     infile.read((char *)&stu[i], sizeof(stu[i]));  // 一次读入文件中的全部数据
      • infile.close();
  • 与文件指针有关的流成员函数
    • // g是输入的标志,p是输出的标志
    • gcount():   返回最后一次输入所读取的字节数
    • tellg():    返回输入文件指针的当前位置
    • seekg(文件中的位置):    将输入文件中指针移到指定的位置
    • seekg(位移量,参考位置):    以参照位置为基础移动若干字节

    • tellp():    返回输出文件指针当前的位置
    • seekp(文件中的位置):    将输出文件中指针移到指定的位置
    • seep(位移量,参考位置):    一参考位置为基础移动若干字节

    • 函数参数中的"文件中的位置"和"位移量"被指定为long型整数,以字节为单位(例如100代表向前100字节,-50代表向后50字节)
    • "参考位置"为:
      • ios::beg: 文件开头    
      • ios::cur: 文件当前位置    
      • ios::end: 文件结尾
    • [备注]:对于fstream定义的变量,seekg和seekp操作的都是同一个指向文件的指针
    • 修改文件中的数据,再重新插入文件中的位置采用的覆盖方式。
    • 举例:写入二进制文件;然后读出数据并修改,再写入;最后输出全部数据
    • #include <fstream>#include <iostream>#include <string>using namespace std;struct student{string name;int num;short age;char sex;};int main( ){student stu[3]={"Li",1001,18,'f',"Fun",1002,19,'m',"Wang",1004,17,'f'};fstream iofile("stu.dat",ios::in|ios::out|ios::binary);if(!iofile){cerr<<"open error!"<<endl;abort( );//退出程序}for(int i=0;i<3;i++)iofile.write((char*)&stu[i],sizeof(stu[i]));// 指向输入文件指针和输出文件指针一样cout << iofile.tellp() << endl;cout << iofile.tellg() << endl;student stud[3];iofile.seekg(sizeof(stud[0]));  // 定位文件指针位置cout << iofile.tellp() << endl;cout << iofile.tellg() << endl;student temp;iofile.read((char*)&temp, sizeof(temp));temp.age = 22;iofile.seekp(sizeof(temp));iofile.write((char*)&temp, sizeof(temp));iofile.seekg(0);  // 定位文件指针位置为最开始,读取所有元素for(i=0;i<3;i++)iofile.read((char*)&stud[i],sizeof(stud[i]));iofile.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;}
参考文章:输入输出流(二)文件操作与文件流
原创粉丝点击