浅学C++(8)C++(C++文件IO)

一、I/O流
    头文件 <fstream>
    C++中把对文件的读写操作都封装在以下类中:
    ofstream 对文件的写操作,继承了ostream类的功能
    ifstream 对文件的读操作,继承了istream类的功能
    fstream  对文件的读写操作,继承了ofstream\ifstream类的功能

二、C++对文本文件的读写操作
    1、创建流对象,通过流对象打开文件
        a、创建流对象并用有参构造打开文件
            ofstream fout(const char *filename,<openmode mode>);
        b、无参构造创建流对象,再通过成员函数打开文件
            void open( const char *filename );
            void open( const char *filename, openmode mode );  
            filename:文件路径  
            mode:文件的打开方式
                ios::app    添加输出 
                ios::ate    当已打开时寻找到EOF 
                ios::binary 以二进制模式打开文件 
                ios::in     为读取打开文件 
                ios::out    为写入打开文件 
                ios::trunc  覆盖存在的文件 
        
        ifstream类 默认只读方式打开文件,文件不存在则失败 r
        ofstream类 默认只写方法打开文件,文件不存在则创建,存在则清空   w
        fstream类 默认读写方式打开文件,文件不存在则失败 r+

    2、判断文件是否打开成功
        a、使用 !类对象名 的方式进行判断
            if(!fin)//失败
            else    //成功
        b、使用 good\fail 成员函数进行判断上一次文件操作是否成功\失败 需要注意返回值

    3、读写文件
        流对象 << 文本数据  写操作
        流对象 >> 变量      读操作
    4、关闭文件
        close();
        注意:只是关闭流对象的当前打开文件,但是流对象依然可以继续打开新文件
    练习1:
        设计一个学生类并创建学生对象,然后把对象的内容以文本形式写入stu.txt中
    练习2:
        从stu.txt中读取出来,并用该内容实例化一个新的学生对象并显示
    
    注意:
        在读写内建类型数据时,原有的<< >>运算符就可以直接进行文本读写,但是在对类对象进行读写操作时,绝大多数的类成员变量是private,因此无法直接在类外进行读写
        由于ostream/istream是ofstream/ifstream的父类,因此如果在它们里面重载了 << >> 运算符,那么除了可以直接通过cout/cin输出输入类对象外,还可以用于直接文本读写类对象,一举两得

三、C++的随机读写
    C++为文件IO流提供了两套设置文件位置指针的成员函数,目的为了兼容有两个位置指针的操作系统,但是UNIX\Linux和Windows系统底层只有一个位置指针,所以使用哪套都可以
    istream &seekg(off_type offset,ios::seekdir origin);
    功能:通过偏移值+基础位置 设置 输入流位置指针的位置
    offset:偏移量
    origin:基础位置
        ios::beg    文件开头
        ios::cur    当前位置
        ios::end    文件末尾
    
    istream &seekg(pos_type position );
    功能:通过 绝对位置 设置输入流位置指针的位置

    ostream &seekp( off_type offset,ios::seekdir origin );
    ostream &seekp( pos_type position );
    功能与seekg类似,用哪个都可以

    pos_type tellg();
    功能:获取输入流的位置指针的位置
    pos_type tellp();
    功能:获取输出流的位置指针的位置

    bool eof();
    功能:判断文件的上一次读操作是否从文件末尾开始读,是返回真

四、C++对二进制文件的读写操作
    1、创建流对象,打开文件
        a、使用有参构造创建并打开文件
        b、使用无参构造创建对象,通过open成员函数打开文件
        mode参数增加 ios::binary (Windows下一定要加)

    2、二进制读写操作
        ostream &write(const char *buffer,streamsize num);
        功能:以二进制方式写入文件
        buffer:待写入数据的内存首地址
        num:要写入的字节
        注意:C++中文件I/O流的write只有两种结果,要么num个字节全部写入成功,要么一个都没有写入,只需要使用 good\fail 判断是否写入成功

        istream &read( char *buffer, streamsize num );
        功能:以二进制方式读文件
        buffer:存储数据的内存首地址
        num:要读取的字节数

        streamsize gcount();
        功能:获取上一次读文件操作时读到的字节数

        注意:在以二进制方式读写对象时,对象的成员不应该有指针(以及string)类型,因为在写入时只会写入指针成员变量(地址编号),而下一次读取该指针变量时,该指针所指向的内存极大可能不是指向上次写入时的内存了,因此读到的该编号没意义了
    
    一直读文件到末尾:
        while(true)
        {
            //读操作 read  fin >> obj
            //其它操作
            if(fs.eof())   break;
        }


    
五、类型信息识别
    C++中使用typeid运算符可以获取数据的类型
    typeid(数据)

    1、返回值是一个类类型对象
    2、该类类型中有一个name成员函数,可以获取数据的类型并转换为字符串
    3、该类重载了 == 运算符 可以判断两个数据是否是同一个类型
    4、它可以区别父类指针或引用指向的是哪个子类,但是前提是父子类之间构成多态

实现Linux命令mv的部分功能

#include <unistd.h>

using namespace std;

int main(int argc,const char* argv[])
{
	if(3 != argc)
	{	
		cout << "User:./a.out <src> <dest>" << endl;
		return 0;
	}
	ifstream ifs(argv[1]);
	if(!ifs.good())
	{
		cout << "源文件不存在,请检查!" << endl;
		return 0;
	}
	if(0 == access(argv[2],F_OK))
	{	
		cout << "目标文件已存在,是否覆盖(y/n)" << endl;
		char cmd;
		cin >> cmd;
		if('y'!=cmd && 'Y'!=cmd)
		{
			    cout << "STOP" << endl;
				ifs.close();
				return 0;
		}
	}

	ofstream ofs(argv[2]);
	if(!ofs.good())
	{
		cout << "无法将源文件移动到该处,请检查该位置" << endl;
		return 0;
	}
	char buf[4096] = {};
	do
	{	
		ifs.read(buf,sizeof(buf));
		ofs.write(buf,ifs.gcount());
	}while(!ifs.eof());

	cout << "移动完成" << endl;

	ifs.close();
	ofs.close();

	remove(argv[1]);
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值