C++ 标准文件的写入读出(ifstream,ofstream)

头文件 < fstream>
c++中有一个stream,所有的I/O都是以这个流类为基础的。继承结构如下图:
这里写图片描述

a.”<<”插入器,向流输出数据;
b.”>>”析取器,向流输出数据;
我们主要讨论ifstream和ofstream
ifstream 和ofsteam 包含在头文件fstream中。
ofstream 是从内存读到硬盘;
ifstream 是从硬盘读到内存。
fstream 是可对打开的文件进行读写操作。

1.打开文件

在fstream类中,成员函数open()实现打开文件的操作,从而将数据流和文件进行关联,通过ofstream,ifstream,fstream对象进行对文件的读写操作。
函数:open()
void open ( const char * filename,ios_base::openmode mode = ios_base::in | ios_base::out );
void open(const wchar_t *_Filename, ios_base::openmode mode= ios_base::in | ios_base::out,int prot = ios_base::_Openprot);

参数: filename 待操作的文件名
mode 打开文件的方式
prot 打开文件的属性

打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:

  • ios::app:  以追加的方式打开文件
  • ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
  • ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
  • ios::in:   文件以输入方式打开(文件数据输入到内存)
  • ios::out:   文件以输出方式打开(内存数据输出到文件)
  • ios::nocreate:不建立文件,所以文件不存在时打开失败
  • ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
  • ios::trunc:  如果文件存在,把文件长度设为0

可以用“或”把以上属性连接起来,如ios::out|ios::binary
Demo

fstream file1;  
file1.open("c:\\config.sys",ios::binary|ios::in,0);
file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0); 
fstream file1("c:\\config.sys"); 
ifstream file2("c:\\pdos.def");//以输入方式打开文件  
ofstream file3("c:\\x.123");//以输出方式打开文件  

所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定

2.关闭文件

file.close()
打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。

3.读写文件

类ofstream, ifstream 和fstream 是分别从ostream, istream 和iostream 中引申而来的。这就是为什么 fstream 的对象可以使用其父类的成员来访问数据。
一般来说,我们将使用这

3.1文本文件的读写

些类与同控制台(console)交互同样的成员函数(cin 和 cout)来进行输入输出。如下面的例题所示,我们使用重载的插入操作符<<
DEMO

ofstream out("out.txt");
if(out.is_open())
{
    out<<"HELLO WORLD!"<<endl;
    out.close();
}
`
结果在文件out.txt中写入了HELLO WORLD!
`
ifstream in("out.txt");
cha buffer[200];
if(in.is_open())
{
    while(!in.eof())
    {
        in.getline(buffer,100)
        cout<<buffer<<endl;
        out.close();
    }
}

结果在屏幕上输出了 :HELLO WORLD!
`
状态标志符的验证(Verification of state flags)

  • bad()
    如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。
  • fail()
    除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。
  • eof()
    如果读文件到达文件末尾,返回true。
  • good()
    这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。

3.2二进制文件的读写

  • write ( char * buffer, streamsize size );//从buffer中读取size个字符,写到文件中。
  • read ( char * buffer, streamsize size );//从文件中读取size个字符到buffer中

这里 buffer 是一块内存的地址,用来存储或读出数据。参数size 是一个整数值,表示要从缓存(buffer)中读出或写入的字符数。

// reading binary file  
    #include <iostream>  
    #include <fstream.h>  
    const char * filename = "test.txt";  
    int main () {  
        char * buffer;  
        long size;  
        ifstream in (filename, ios::in|ios::binary|ios::ate);  
        size = in.tellg();  
        in.seekg (0, ios::beg);  
        buffer = new char [size];  
        in.read (buffer, size);  
        in.close();  
        cout << "the complete file is in a buffer";  
        delete[] buffer;  
        return 0;  
    }  
//运行结果:  
The complete file is in a buffer  `
  • put()
      ofstream &put(char ch),使用:
      file1.put(’c’) //就是向流写一个字符 ‘c’。
  • get()
    (1).ifstream &get(char ch),使用:
    file1.get(x)//从文件中读取一个字符存储在x中
    (2).ifstream &get(char *buf,int num,char delim=’\n’),从文件中读取长度为num的字符串到buf中,或者读取到delim为止,使用:
    file2.get(str1,127,’A’); //从文件中读取字符到字符串str1,当遇到字符’A’或读取了127个字符时终止。

4.文件定位

和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。相应的函数:

  • seekg():
    istream &seekg(streamoff offset,seek_dir origin);//设置读位置,
  • seekp()
    ostream &seekp(streamoff offset,seek_dir origin); //设置写位置
    定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:

  • ios::beg:  文件开头

  • ios::cur:  文件当前位置
  • ios::end:  文件结尾
    DEMO
    file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
    file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节

5.缓存和同步(Buffers and Synchronization)

当我们对文件流进行操作的时候,它们与一个streambuf 类型的缓存(buffer)联系在一起。这个缓存(buffer)实际是一块内存空间,作为流(stream)和物理文件的媒介。例如,对于一个输出流, 每次成员函数put (写一个单个字符)被调用,这个字符不是直接被写入该输出流所对应的物理文件中的,而是首先被插入到该流的缓存(buffer)中。
当缓存被排放出来(flush)时,它里面的所有数据或者被写入物理媒质中(如果是一个输出流的话),或者简单的被抹掉(如果是一个输入流的话)。这个过程称为同步(synchronization),它会在以下任一情况下发生:

  • 当文件被关闭时: 在文件被关闭之前,所有还没有被完全写出或读取的缓存都将被同步。
  • 当缓存buffer 满时:缓存Buffers 有一定的空间限制。当缓存满时,它会被自动同步。
  • 控制符明确指明:当遇到流中某些特定的控制符时,同步会发生。这些控制符包括:flush 和endl。
  • 明确调用函数sync(): 调用成员函数sync() (无参数)可以引发立即同步。这个函数返回一个int 值,等于-1 表示流没有联系的缓存或操作失败。
  • 28
    点赞
  • 156
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值