【C/C++】fstream详解

一、概述

C中对文件的操作是通过 FILE文件指针 和相关关函数来实现的。

C++中是通过 fstream文件流 来实现的,其包含 ifstreamofstreamfstream 三个类,通过定义这三个类的对象实现相对应的文件操作。

二、C中的文件操作

1、打开文件

包括 fopen()freopen()tmpfile() 三个函数,他们都会返回一个指向 FILE 对象的指针。该 FILE 对象包控制被打开文件相关联的流的所有信息,包括指向缓冲区的指针、文件位置指示器、指示错误和文件结尾情况的标志等。如果成功,该指针就指向已打开的流,如果失败,该指针就为空指针

打开文件后就可以调用相关函数对流进行处理。这些函数都把指向 FILE 对象的指针(FILE 指针)作为它们的参数之一。

FILE *fopen(const char * restrict filename, const char * restrict mode);
FILE *freopen(const char * restrict filename, const char * restrict mode, FILE * restrict stream);
FILE *tmpfile(void);
/*
 * For example 
 */
#include <stdio.h>
#include <stdbool.h>

_Bool isReadWriteable( const char *filename )
{
    FILE *fp = fopen( filename, "r+" ); //打开一个文件以用于读写
    if ( fp != NULL ) //fopen()是否执行成功
    { 
        fclose(fp);   //成功:关闭文件,没有错误需要处理
        return true;
    }else{ 
        return false; // 失败
    }
}

 2、关闭文件

关闭文件时需要使用函数 fclose() 。关闭成功返回 0;异常返回 EOF,表示文件在关闭时发生错误。

int fclose( FILE *fp );

三、C++中的文件操作

C++中是通过 fstream 文件流(以及其成员函数)实现对文件的操作,头文件如下所示,其包含三个类:

  • ifstream(代表输入文件,从硬盘到内存,支持 >> 操作符)
  • ofstream(代表输出文件,从内存到硬盘,支持 << 操作符)
  • fstream(代表输入输出文件,同时支持 >><< 操作符)
​#include <fstream> //头文件
ofstream    //文件写操作,内存写入存储设备
ifstream    //文件读操作,存储设备读取到内存中
fstream     //读写操作,对打开的文件可进行读写操作

文件流的 常用成员函数 如下所示。从 bad() 函数开始为验证流状态的常用成员函数,返回值均为 bool 型。

  • open(),打开文件
  • close(),关闭文件
  • read(),顺序读数据
  • write(),顺序写数据
  • is_open(),判断文件是否打开,打开则返回true
  • bad(),如果在读写过程中出错,返回true
  • fail(),除了与bad()同样的情况下返回true外;遇到格式错误时也返回true,例如当需要读入一个int ,而得到一个char
  • eof(),如果读文件到达文件的末尾,返回true
  • good(),最通用的验证,如果遇上以上任何一个函数返回true的话,此函数返回false
  • clear(),重置以上成员函数所检查的状态标志,没有参数

1、打开文件——Open()函数

Open()函数如下,其中 filename 代表操作文件名、mode 代表打开方式、prot 代表打开文件属性

/*
 * 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);

/* Mode的可选参数 */
ios::in     为输入(读)而打开文件
ios::out    为输出(写)而打开文件
ios::ate    初始位置:文件尾
ios::app    所有输出附加在文件末尾
ios::trunc  如果文件已存在先删除文件
ios::binary 二进制方式

/* Prot的可选参数 */
0   普通文件,打开文件
1   只读文件
2   隐含文件
3   系统文件

打开文件的方式可以单一使用,或者使用 '|' 组合使用

ofstream outfile;
outfile.open("Hello.txt", ios::in|ios::out|ios::binary);

若仅使用默认的打开方式可以不用显式的调用open()函数,直接使用流对象进行文件的操作。当使用默认的方式打开文件时,可以使用成员函数 is_open() 对文件进行是否已打开的验证。 

ofstream out("\\\", ios::out);
ifstream in("\\\", ios::in);
fstream iofile("\\\", ios::in|ios::out);

2、关闭文件——Close()函数

Close()函数,对文件进行完读写操作之后,必须将文件关闭使得文件重新变成可以访问的。close()函数负责将缓存中的数据排放出来并关闭文件。

3、文本文件的读写

文本文件的读/写可以利用 << >> 分别进行写和读

#include <fstream.h>
#include <iostream.h>
using namespace std;

int main() {...}

void func1(...) //文件的写操作
{
    ofstream file("out.txt"); 
    if(file.is_open())
    {
        fil e<< "This is a test" << endl; 
        file.close();
    }
}

void func2(...) //文本的读入,并打印在屏幕上
{
    char buff[520];
    ifstream infile("in.txt");
    if(!infile.is_open())
        cout << "Error open" << endl;
    while(!infile.eof())
    {
        infile.getline(buff, 100);
        cout << buff << endl;
    }
    return 0;
}                               

通过 read()write() 函数进行读写,它们是文件流为顺序读写数据特殊设计的成员函数。write是 ostream 的成员函数,read是 istream 的成员函数,类 fstream 的对象同时拥有这两个函数。

其原型如下, buffer 是一块用来存储或读出数据的内存地址,size 表示要从 buffer 中读出或写入的整数值。

write(char * buffer, streamsize size);
read(char * buffer, streamsize size);

4、获取和设置流指针

所有输入/输出流对象都有至少一个流指针:

  • ifstream,类似istream,有一个被称为get pointer的指针,指向下一个将被读取的元素;
  • ofsream,类似ostream,有一个被称为put pointer的指针,指向下一个元素的位置;
  • fstream,类似iostream,同时继承了 get 和 put ;

读取/配置流指针的成员函数

  • tellg() 和 tellp(),这两个函数不用传入参数,返回pos_type类型的值,即一个整数,代表当前get流指针的位置(用tellg)或put流指针的位置(用tellp)。
  • seekg() 和 seekp(),这对函数分别用来改变指针get和put的位置。两个函数都被重载为两种不同的原型:
//使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置;
//要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。
seekg(pos_type position);
seekp(pos_type position);

//使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。
seekg(off_type offset, seekdir direction);
seekp(off_type offset, seekdir direction);
//direct的可选参数
//ios::beg	从流开始位置计算的位移
//ios::cur	从流指针当前位置开始计算的位移
//ios::end	从流末尾处开始计算的位移

需要注意的是,流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本文件中某些特殊字符可能被修改。因此,建议

  • 对以文本文件模式打开的文件总是使用 seekg 和 seekp 的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改;
  • 对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生;
//获取二进制文件的大小
#include <iostream.h>
#include <fstream.h>
    
const char * filename = "test.txt";
    
int main() 
{
    long l,m;
    ifstream in(filename, ios::in|ios::binary);
    l = in.tellg();
    in.seekg (0, ios::end);
    m = in.tellg();
    in.close();
    cout << "size of " << filename;
    cout << " is " << (m-l) << " bytes.\n";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值