C++中fstream
Posted 轻览月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中fstream相关的知识,希望对你有一定的参考价值。
#include <fstream>
头文件fstream包含了ifstream、ofstream、fstream三个类,可以通过定义这三个类的对象来实现相对应的文件操作。
#include <fetream>
ofstream //文件写操作,内存写入存储设备
ifstream //文件读操作,存储设备读取到内存中
fstream //读写操作,对打开的文件可进行读写操作
1.打开文件
- 函数 open()
public member function
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::in | 为输入(读)而打开文件 |
---|---|
ios::out | 为输出(写)而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 所有输出附加在文件末尾 |
ios::trunc | 如果文件已存在先删除文件 |
ios::binary | 二进制方式 |
- 打开文件的方式可以单一使用或者利用“|”组合使用,例如:
ofstream outfile;
outfile.open("Hello.txt",ios::in|ios::out|ios::binary)
- 打开文件的属性在ios类中也有定义:
0 | 普通文件,打开文件 |
---|---|
1 | 只读文件 |
2 | 隐含文件 |
3 | 系统文件 |
对于文件的属性也可以利用“|”和“+”进行组合使用
- 如果只是使用默认的打开方式可以不用显式的调用open()函数,直接使用流对象进行文件的操作,如:
ofstream out("\\\\\\",ios::out);
ifstream in("\\\\\\",ios::in);
fstream fil("\\\\\\",ios::in|ios::out);
当使用默认的方式对文件进行打开时,可以使用成员函数is_open()对文件进行是否已打开的验证。
2.关闭文件
- 函数close()
对文件进行完读写操作之后,必须将文件关闭使得文件重新变成可以访问的。close()函数负责将缓存中的数据排放出来并关闭文件。关闭的只是流对象所打开的文件,仍然可以利用流对象去打开别的文件。
3.文本文件的读写
文本文件的读写可以如同类与控制台交互一样利用"<<”和">>"分别进行写和读,如:
#include<fstream.h>
int main()
ofstream file("out.txt");
if(file.is_open())
file<<"This is a test"<<endl;
file.close();
//文件的写操作
#include <fstream.h>
#include <iostream.h>
using namespace std;
int main()
char buff[256];
ifstream infile("in.txt");
if(!infile.is_open())
cout<<"Error open"<<endl;
while(!infile.eof())
infile.getline(buff,100);
cout<<buff<<endl;
return 0;
//文本的读入,并打印在屏幕上
状态标志符的验证
有一些验证流的状态的成员函数(所有都返回bool型返回值):
- bad()
如果在读写过程中出错,返回true. - fail()
除了与bad()同样的情况下返回true外,加上格式错误时也返回true,例如当想要读入一个整数 ,而得到一个字母。 - eof()
如果读文件到达文件的末尾,返回true。 - good()
最通用的验证:如果遇上以上任何一个函数返回true的话,此函数返回false。 - clear()
重置以上成员函数所检查的状态标志,没有参数。
获得和设置流指针
所有输入/输出流对象都有至少一个流指针:
- ifstream,类似istream,有一个被称为get pointer的指针,指向下一个将被读取的元素。
- ofsream,类似ostream,有一个被称为put pointer的指针,指向下一个元素的位置。
- fstream,类似iostream,同时继承了 get 和 put 。
可以使用以下成员函数来读取或配置流指针:
- tellg()和tellp()
这两个函数不用传入参数,返回pos_type类型的值,即一个整数,代表当前get流指针的位置(用tellg)或put流指针的位置(用tellp)。 - seekg()和seekp()
这对函数分别用来改变指针get和put的位置。两个函数都被重载为两种不同的原型:
seekg(pos_type position);
seekp(pos_type position);
使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。
seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );
使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:
ios::beg | 从流开始位置计算的位移 |
---|---|
ios::cur | 从流指针当前位置开始计算的位移 |
ios::end | 从流末尾处开始计算的位移 |
流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生。
// obtaining file size
#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;
//`获取二进制文件的大小
4.二进制文件
在二进制文件中,使用<< 和>>,以及函数(如getline)来操作符输入和输出数据,没有什么实际意义,虽然它们是符合语法的。
文件流包括两个为顺序读写数据特殊设计的成员函数:write 和 read。第一个函数 (write) 是ostream 的一个成员函数,都是被ofstream所继承。而read 是istream 的一个成员函数,被ifstream 所继承。类 fstream 的对象同时拥有这两个函数。它们的原型是:
write ( char * buffer, streamsize size );
read ( char * buffer, streamsize size );
这里 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
如何使用 fstream::open() 检查 C++ 中是不是存在文件
【中文标题】如何使用 fstream::open() 检查 C++ 中是不是存在文件【英文标题】:How to check if a file exists in C++ with fstream::open()如何使用 fstream::open() 检查 C++ 中是否存在文件 【发布时间】:2014-10-03 06:12:23 【问题描述】:我正在使用 fstream 库来处理文件。基本上,我需要知道某个文件是否存在。在 c++ 在线文档中,关于 open() 的内容如下:
返回值
无
如果函数打开文件失败,则设置失败位状态标志 对于流(如果该状态标志可能会抛出 ios_base::failure 已使用成员异常注册)。
它说没有指定返回值。但是在失败的情况下,会设置一个标志。我的问题是,我应该然后访问该标志,或者更好地问,我应该如何查看open()
是否成功。
到目前为止我有这个代码:
int Log::add()
fstream fileStream;
fileStream.open("logs.txt");
【问题讨论】:
fileStream.is_open()
? en.cppreference.com/w/cpp/io/basic_ifstream/is_open
那么在失败的情况下标志和异常呢? is_open 经常在 open() 之后立即使用吗?
C++ 在那个领域相当糟糕。有两个标志:fail
和bad
可以测试,但它不会告诉您文件是否受到保护或不存在或路径错误...
【参考方案1】:
如果文件无法打开,它会设置故障位。所以你可以检查那个位:
fileStream.open("logs.txt");
if (fileStream.fail())
// file could not be opened
实际上,if (fileStream)
也可以在这里工作,因为 ios
(ifstream
、ofstream
和 fstream
的基类)有一个到 bool
的转换运算符。
不用担心失败异常。您可以通过调用ios::exceptions
请求在失败时抛出异常,但默认情况下不会在失败时抛出异常。
请注意,这并没有告诉您为什么文件无法打开。可能是该文件不存在,路径中的目录不存在,您无权打开该文件,您的程序已达到可以打开的文件数限制,等等在。没有可移植的方法来确定原因。
【讨论】:
请注意,使用is_open()
更安全。至少在我的经验中,坏位和失败位并不总是在调用之间正确重置...
另请注意.good()
,这表示eofbit
failbit
和badbit
中的所有三个都未设置,这也会捕获EOF 条件。【参考方案2】:
请注意,“文件存在”和“文件可以打开”是有区别的。
要检查文件是否存在(并且您确实不需要打开/读取/写入文件),请使用fstat
或其 c++ 对应项 - 您不需要任何权限即可查询信息。
请注意,如果您想在打开文件之前检查文件是否存在,那么您做错了。在您的检查和实际打开文件的尝试之间,情况可能已经改变。通常,您只需使用打开/创建选项直接打开文件,无需事先检查。
【讨论】:
什么是“它的 c++ 对应物”?【参考方案3】:您的方法不检查是否存在,而是检查可访问性。可以像这样检查存在性:
#include <sys/stat.h>
inline bool exists (const std::string& filename)
struct stat buffer;
return (stat (filename.c_str(), &buffer) == 0);
在 C++14 中可以这样使用:
#include <experimental/filesystem>
bool exist = std::experimental::filesystem::exists(filename);
& 在 C++17 中:(reference)
#include <filesystem>
bool exist = std::filesystem::exists(filename);
【讨论】:
【参考方案4】:有is_open
、fail
两种方法,例如:
string path = "not_exists.txt";
ifstream fin(path);
if(fin.is_open())
cout<<"file is open"<<endl;
else
cout<<"file isn't open"<<endl;
if(fin.fail())
cout<<"file open fail"<<endl;
else
cout<<"file open success"<<endl;
输出如下:
见: http://www.cplusplus.com/reference/fstream/ifstream/供参考。
【讨论】:
以上是关于C++中fstream的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV 与 Objective C 与 Objective C++