C++文件读写

本文详细介绍了C++中I/O流(包括fstream、ofstream和ifstream)的基本概念、文本文件的读写方法、随机读写操作以及二进制文件的处理,还提供了一个简易的MV命令示例,涉及文件打开、关闭、权限检查和覆盖检查。
摘要由CSDN通过智能技术生成

一、C++ I/O流

头文件:fstream

C++把对文件的读写操作都封装在以下的类中:

ofstream类对文件的写操作,继承了ostream类的功能

ifstream类对文件的读操作,继承了istream类的功能

fstream类对文件读写操作,继承了ofstream、ifstream类的功能

二、C++对文本文件的读写

1、创建流对象,通过流对象打开文件

①ofstream ofs(const char *filename, openmode mode );

②通过成员函数方式,打开文件

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类,默认以只读方式O_RDONLY打开文件,文件不存在则失败 “r”

ofstream类,默认以只写方式O_WRONLY|O_CREAT|O_TRUNC打开文件,文件不存在则创建、存在则清空 “w”

fstream类 默认以读写方式O_RDWR打开文件,文件不存在则失败,文件存在不清空 “r+”

注意:ios::里面打开模式单独使用和混合使用时候有些功能会有所删减变化,不是简单的功能相加,具体底层调用哪个打开模式可以通过 strace ./a.out 来追踪底层对系统函数的调用

2、如何判断文件是否打开成功

①通过 !流对象名 执行了该类的!运算符重载版本

if(!ifs)   //  为真 失败    

②通过good\fail成员函数判断是否成功

bool good();

功能:判断上一次流操作是否成功,成功返回真,一般用于判断文件是否打开成功

3、读写文件

流对象 << 写操作

流对象 >> 读操作

4、关闭文件

成员函数:

void close(void)

注意:只是关闭流对象当前的文件,但是流对象没有销毁,还可以继续通过open成员函数重新打开别的文件

5、如何以文本方式读写类对象

读写类对象时绝大部分成员变量都是私有的,因此无法直接在类外进行读写

由于ostream/istream分别是ofstream/ifstream的父类,因此如果重载了>> <<运算符,既可以用于平时输出、输入类对象,并且还可以直接用于类对象的文本方式流操作读写

重载前重载后
cout << 类对象ofs << 类对象
cin >> 类对象ifs >> 类对象

三、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 );

功能:通过绝对值的方式设置位置指针的位置

seekp 功能类似

pos_type tellp();

功能:获取位置指针所在文件的绝对位置

tellg功能类似

四、C++对二进制文件的读写操作

1、创建流对象、打开文件

ios::binary 以二进制模式打开文件

2、读写操作
ostream &write( const char *buffer, streamsize num );

功能:以二进制方式写文件

buffer:待写入数据的内存首地址

num:待写入的字节数

注意:C++的write只会有两种结果,要么num个字节全部写入,要么一个都没写入,可以通过good、fail判断上一次的写操作是否成功

istream &read( char *buffer, streamsize num );

功能:以二进制方式读文件

buffer:存储读取到的数据的内存首地址

num:要读取的字节数

streamsize gcount();

功能:获取上一次读操作中成功读取到的字节数

bool eof();

功能:判断读操作是否读到了文件末尾,如果是返回真

3、二进制读写需要注意的问题:

①对象的成员变量中不应该有指针类型(或string类型),因为此时写入时只会把指针变量存储的地址写入,而下次读取到该指针变量时,该指针地址已经没有意义了

②一直读取二进制文件

while(true)
{    
	//  读操作
	if(fs.eof()) break; 
	//  读成功,执行相应操作
}
使用C++实现一个简易mv带覆盖检查的命令
#include <iostream>
#include <unistd.h>
#include <fstream>
using namespace std;

int main(int argc,const char* argv[])
{
	if(3 != argc)
	{
		cout << "User: ./MV <src> <dest>" << endl;
		return -1;
	}

	ifstream ifs(argv[1]);
	if(!ifs)
	{
		cout << "原文件不存在,请检查!" << endl;
		return -1;
	}

	if(0 == access(argv[2],F_OK))
	{
		cout << "目标文件已存在,是否覆盖(y/n)?" << endl;
		char cmd;
		cin >> cmd;
		if('y' != cmd)
		{
			cout << "停止移动!" << endl;
			ifs.close();
			return 0;
		}
	}
	
	ofstream ofs(argv[2]);
	if(!ofs)
	{
		cout << "目标位置无权限,请检查!" << endl;
		ifs.close();
		return -1;
	}
	
	char buf[4096] = {};
	while(true)
	{
		ifs.read(buf,sizeof(buf));
		if(ifs.eof()) break;
		ofs.write(buf,ifs.gcount());
	}

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

	unlink(argv[1]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值