c++ 文件操作

以下是c++标准中的文件操作方法。
c++的文件操作需要用到下面这三个类

  • ofstream: 写操作(输出)的文件类 (由ostream继承而来)
  • ifstream: 读操作(输入)的文件类(由istream继承而来)
  • fstream: 可同时读写操作的文件类 (由iostream继承而来)
    这里写图片描述
    从上图是各个类的继承关系,fstream是iostream的子类

Node:

  • 确保include<fstream>
  • 在名称空间std下

#open,close#
有两个两个函数非常重要。open函数会通知操作系统我们要读写某个文件了。这样别的程序就不能再改写这这文件了。避免了文件读写时的错乱。close函数会告诉操作系统,文件操作可以结束了。别的程序可以操作这个文件了。同时也可以去操作别的文件了

**open **
void open (const char * filename, openmode mode);
第一个参数,是我们想要打开的文件路径
第二个参数未打开方式的一组组合(通过|)

  • ios::out 为输出(写)而打开文件
  • ios::ate 初始位置:文件尾
  • ios::app 所有输出附加在文件末尾
  • ios::trunc 如果文件已存在则先删除该文件
  • ios::binary 二进制方式

该参数在不同的文件对象中是有缺省值的

  • ofstream对象为 ios::out | ios::trunc
  • ifstream 对象为ios::in
  • fstream 对象为ios::in | ios::out

close
void close ();

Node:

opne 方法已经整合到构造函数中了。我们可以只需要调用相应参数的构造函数就可以不用调用open函数了.其实open在visual c++还有第三个参数,负责说明文件保护方式,因为不是c++标准,所以我们也不知道干什么的
这里写图片描述

close 已经整合到析构函数中了,所以我们其实也可以不用直接调用

#文本操作#
对于文本方面的操作,我们可以像在控制台上操作一样使用重载了的操作符号**<<>>**和对应的一些读写操作的函数如get,getline,put。

//#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>

using namespace std;
int main() {
	ofstream of("lean.text");
	if (of.is_open()) {
		of << "I'm wen";
		of.close();
	}
	return 0;
}

//#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
using namespace std;
int main() {


	char buffer[256];
	ifstream inputf("lean.text");
	if (!inputf.is_open()){

		cout << "Error" << endl;
		exit(1);
	}
	//下面会用到一些特殊标识,下面会说
	while (!inputf.eof()) {

		inputf.getline(buffer, 100);
		cout << buffer << endl;
		
	}
	cin.get();
	return 0;
}

##相关标志##

这里写图片描述
上图是我在cplusplus上找的可以很好的说明相关函数的作用和返回值
Node:
当出现上述标志时,可以使用clear()函数来重置标志。

#二进制文件#
对二进制文件操作之前我们要在open第二个参数设置为ios::binary.这样fstream就会用二进制来处理文件了。
对于二进制文件,如果我们可以像处理文本一样,使用>>,<<或者getline函数。但是通常这些是无意义的。所以我们用到了另两函数

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

他们会分别读取(写入)流中一段的数据,很适合处理二进制流。那么问题来了我们怎么定位数据段呢?就要说一说流指针了

#流指针(get and put stream pointers)#
流指针,get pointer指针指向下一个将被读取的元素。 put pointer指针指向写入下一个元素的位置。

tellg() 和 tellp()
这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前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 );

seekdir

  • ios::beg 从流开始位置计算的位移
  • ios::cur 从流指针当前位置开始计算的位移
  • ios::end 从流末尾处开始计算的位移

Node:

流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生。

下面代码会读取文件大小


#include<iostream>
#include<fstream>

using namespace std;
int main() {

	long l, m;
	ifstream inputf("..\\Debug\\c++iostream.exe", ios::in | ios::binary);
	l = inputf.tellg();
	inputf.seekg(0, ios::end);
	m = inputf.tellg();
	inputf.close();
	cout << "size of " << "c++iostream.exe";
	cout << " is " << (m - l) << " byte.\n";
	system("PAUSE");
	return 0;
}

#缓存和同步(Buffers and Synchronization)#
当我们对文件流进行操作的时候,它们与一个streambuf 类型的缓存(buffer)联系在一起。这个缓存(buffer)实际是一块内存空间,作为流(stream)和物理文件的媒介。例如,对于一个输出流, 每次成员函数put (写一个单个字符)被调用,这个字符不是直接被写入该输出流所对应的物理文件中的,而是首先被插入到该流的缓存(buffer)中。

当缓存被排放出来(flush)时,它里面的所有数据或者被写入物理媒质中(如果是一个输出流的话),或者简单的被抹掉(如果是一个输入流的话)。这个过程称为同步(synchronization),它会在以下任一情况下发生:

  • 当文件被关闭时: 在文件被关闭之前,所有还没有被完全写出或读取的缓存都将被同步。
  • 当缓存buffer 满时:缓存Buffers 有一定的空间限制。当缓存满时,它会被自动同步。
  • 控制符明确指明:当遇到流中某些特定的控制符时,同步会发生。这些控制符包括:flush 和endl。

Node:
明确调用函数sync(): 调用成员函数sync() (无参数)可以引发立即同步。这个函数返回一个int 值,等于-1 表示流没有联系的缓存或操作失败

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值