C++ - 文件读写

5 文件操作

C++文件操作介绍

文件是指存储在计算机文件系统中的数据集合。文件可以包含各种类型的信息,例如文本、图像、音频视频等。在 C++中,文件是一种数据流,可以用于读取或写入数据。C++提供了一系列的文件操作函数,用于实现对文件的读取、写入、打开、关闭等操作。

在 C++中,文件可以分为文本文件和二进制文件。这两种文件的区别在于它们存储数据的方式:

文本文件:文本文件以字符形式存储数据,例如 ASCII 或 Unicode 字符。每个字符占用一个字节的空间。文本文件通常用于存储文本信息,如代码、配置文件、文档等。

二进制文件:二进制文件以字节形式存储数据,每个数据项可以是任意长度。二进制文件通常用于存储非文本信息,如图像、音频、视频等。

文本文件是包含可读字符的文件,例如.txt和.csv等文件通常是文本文件。图像、音频和视频等文件是二进制文件,因为它们包含嵌入在其中的二进制数据。图像文件通常包括.bmp、.jpg、.png等格式,音频文件通常包括.wav、.mp3等格式,视频文件通常包括.mp4、.mov等格式。

文件的路径可以使用字符串表示。文件路径可以是相对路径或绝对路径。

相对路径是相对于当前工作目录的路径。当前工作目录是执行程序时操作系统指定的默认路径。例如,如果当前工作目录是 D:\Test\John,而文件位于该目录下的子目录 Files 中,可以使用相对路径来表示文件路径:"Files/myfile.txt"。

绝对路径是文件的完整路径,包括驱动器名(在Windows系统中)或根目录符号(在类Unix系统中)。绝对路径从文件系统的根目录开始。例如,在Windows系统中,文件 myfile.txt 位于 D:\Test\John\Files,可以使用绝对路径来表示文件路径:" D:\Test\John\Files/myfile.txt"。

 

文件类型分为两种:

  1. 文本文件 - 文件以文本的ASCII码形式存储在计算机中

  2. 二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们

 

在C++中,文件的读写主要通过<fstream>库中的ifstream类来进行文件的读操作,通过ofstream类来进行文件的写操作。

操作文件的三大类:

  1. ofstream:写操作

  2. ifstream: 读操作

  3. fstream : 读写操作

 

文件打开的方式:

打开方式 解释
ios::in 为读文件而打开文件
ios::out 为写文件而打开文件
ios::ate 初始位置:文件尾
ios::app 追加方式写文件
ios::trunc 如果文件存在先删除,再创建
ios::binary 二进制方式

注意: 文件打开方式可以配合使用,利用 | 操作符

例如:以追加的方式写文件 ofs.open("test.txt", ios::app | ios:: out)

 

存储单位转换:

 

5.1文本文件

5.1.1写文件

写文件步骤如下:

  1. 包含头文件

    #include <fstream>

  2. 创建流对象

    ofstream ofs;

  3. 打开文件

    ofs.open("文件路径",打开方式);

  4. 写数据

    ofs << "写入的数据";

  5. 关闭文件

    ofs.close();

示例:

#include <fstream>

void test01()
{
	ofstream ofs;
	ofs.open("test.txt", ios::out);
    if (!ofs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;
	}


	ofs << "姓名:张三" << endl;
	ofs << "性别:男" << endl;
	ofs << "年龄:18" << endl;

	ofs.close();
}

int main() {

	test01();

	system("pause");

	return 0;
}

总结:

  • 文件操作必须包含头文件 fstream

  • 读文件可以利用 ofstream ,或者fstream类

  • 打开文件时候需要指定操作文件的路径,以及打开方式

  • 利用<<可以向文件中写数据

  • 操作完毕,要关闭文件

 

 

5.1.2读文件

读文件与写文件步骤相似,但是读取方式相对于比较多

读文件步骤如下:

  1. 包含头文件

    #include <fstream>

  2. 创建流对象

    ifstream ifs;

  3. 打开文件并判断文件是否打开成功

    ifs.open("文件路径",打开方式);

  4. 读数据

    四种方式读取

  5. 关闭文件

    ifs.close();

示例:

#include <fstream>
#include <string>
void test01()
{
	ifstream ifs;
	ifs.open("test.txt", ios::in);

	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;
	}

	//第一种方式:采用“>>”运算符
	//char buf[1024] = { 0 };
	//while (ifs >> buf)
	//{
	//	cout << buf << endl;
	//}

	//第二种方式:利用ifs流对象内部的getline方法,这个名字虽然和第三种中的一样,但是传入的参数不同,并不是同一个函数
	//char buf[1024] = { 0 };
	//while (ifs.getline(buf,sizeof(buf)))
	//{
	//	cout << buf << endl;
	//}

	//第三种方式:利用<string>中的getline函数,按行读取,这样每一行内的所有空格也可以顺利读取
	//string buf;
	//while (getline(ifs, buf))
	//{
	//	cout << buf << endl;
	//}

    //第四种方式:利用ifs内部的get()函数一个个的将字符读出来,遇到EOF时返回False退出while循环,EOF 是 end of file的标志,不太建议使用这个,因为这个很慢,只能一个一个字符读取
	char c;
	while ((c = ifs.get()) != EOF)
	{
		cout << c;
	}

	ifs.close();


}

int main() {

	test01();

	system("pause");

	return 0;
}

总结:

  • 读文件可以利用 ifstream ,或者fstream类

  • 利用is_open函数可以判断文件是否打开成功

  • close 关闭文件

 

 

 

5.2 二进制文件

以二进制的方式对文件进行读写操作

打开方式要指定为 ==ios::binary==

 

5.2.1 写文件

值得一提的是,要实现以二进制形式读写文件,<< 和 >> 将不再适用,需要使用 C++ 标准库专门提供的 read() 和 write() 成员方法。

二进制方式写文件主要利用流对象调用成员函数write

函数原型 :ostream& write(const char * buffer,int len);

参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数

示例:

#include <fstream>
#include <string>

class Person
{
public:
	char m_Name[64];
	int m_Age;
};

//二进制文件  写文件
void test01()
{
	//1、包含头文件

	//2、创建输出流对象
	ofstream ofs("person.txt", ios::out | ios::binary);
	
	//3、打开文件
	//ofs.open("person.txt", ios::out | ios::binary);

	Person p = {"张三"  , 18};

	//4、写文件
	ofs.write((const char *)&p, sizeof(p));

	//5、关闭文件
	ofs.close();
}

int main() {

	test01();

	system("pause");

	return 0;
}

总结:

  • 文件输出流对象 可以通过write函数,以二进制方式写数据

 

 

5.2.2 读文件

二进制方式读文件主要利用流对象调用成员函数read

函数原型:istream& read(char *buffer,int len);

参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数

示例:

#include <fstream>
#include <string>

class Person
{
public:
	char m_Name[64];
	int m_Age;
};

void test01()
{
	ifstream ifs("person.txt", ios::in | ios::binary);
	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
	}

	Person p;
	ifs.read((char *)&p, sizeof(p));

	cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}
  • 文件输入流对象 可以通过read函数,以二进制方式读数据 

 

 

5.3 获取文件大小

方式一:推荐使用此方式获得文件大小

C/C++、Window、Linux 环境都可以使用!

通过结构体struct stat获得。

需要包含头文件:#include <sys/stat.h> // struct stat

#include <iostream>
using namespace std;

#include <sys/stat.h> // struct stat


//通过stat结构体获得文件大小,单位字节
size_t getFileSize1(const char* fileName)
{
	if (fileName == NULL)
	{
		return 0;//这是一个存储文件(夹)信息的结构体,其中有文件大小和创建时间、访问时间、修改时间等
	}
	struct stat statbuf;//提供文件名字符串,获得文件属性结构体
	stat(fileName, &statbuf);// 获取文件大小
	size_t filesize = statbuf.st_size;
	return filesize;
}


int main()
{

	size_t filesize = getFileSize1("test.txt");

	cout << "文件大小:" << filesize << endl;

	return 0;
}

首先也是通过stat函数获得文件的基本属性,然后再从结构体中直接进行获取文件大小就行,很简单,也很好用。

 

方式二:C++ 方式获得文件大小,使用std::ifstreamstd::ios::binary打开文件,然后调用tellg()seekg()函数获取文件大小。

不推荐使用此方式

当文件太大时,移动文件光标指针会非常耗时!

#define _CRT_SECURE_NO_WARNINGS


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


int getFileSize(const std::string& filename) 
{
    std::ifstream file(filename, std::ios::binary | std::ios::ate);//ate 初始位置:文件尾
    if (!file) 
    {
        std::cerr << "Failed to open file: " << filename << std::endl;
        return -1; // or throw an exception
    }
    std::streampos size = file.tellg();
    return static_cast<int>(size);
}

int main()
{

	size_t filesize = getFileSize("test.txt");

	cout << "文件大小:" << filesize << endl;

	return 0;
}

或者:

#include <iostream>
using namespace std;
#include <fstream>
#include <string>


std::streampos getFileSize(std::string fileName)
{ 
	//打开文件
	std::ifstream file;
	file.open(fileName, std::ios::in);
	if (file.is_open() == false)
	{
		// 文件打开失败
		std::cout << "Open file " << fileName << " fail!" << std::endl;
		return -1;
	}
	//文件指针移动到末尾位置
	file.seekg(0, std::ios_base::end);
	//获取当前文件指针位置,也就是获得文件大小
	std::streampos fileSize = file.tellg();
	//文件指针移动到开头文件
	file.seekg(0, std::ios_base::beg);
	//关闭文件
	file.close();
	return fileSize;
}

int main()
{

	size_t filesize = getFileSize("test.txt");

	cout << "文件大小:" << filesize << endl;

	return 0;
}

 

5.4 判断文件读取结束

c++怎么判断文件读取结束

在C++中,可以使用以下方法来判断文件读取是否结束:

1、使用eof()函数:eof()函数检查文件流对象是否已经达到文件末尾。它返回一个bool值,如果已经到达文件末尾,则返回true,否则返回false。可以在循环中使用该函数来判断文件是否读取结束。

例如:

ifstream file("example.txt");
string line;
 
while (!file.eof()) 
{
    getline(file, line);
    // 处理读取的行数据
}

 

2、使用good()函数:good()函数用于检查文件流对象的状态是否正常。如果流对象正常且未发生任何错误,则该函数返回true,否则返回false。因此,可以在循环中使用该函数来判断文件是否读取结束。

例如:

ifstream file("example.txt");
string line;
 
while (file.good()) 
{
    getline(file, line);
    // 处理读取的行数据
}

 

3、使用peek()函数:peek()函数用于查看下一个字符,但并不从输入流中提取该字符。如果文件已经到达末尾,peek()函数将返回EOF(或者-1)。可以在循环中使用该函数来判断文件是否读取结束。

例如:

ifstream file("example.txt");
string line;
 
while (file.peek() != EOF) 
{
    getline(file, line);
    // 处理读取的行数据
}

 

posted @ 2023-10-11 14:54  [BORUTO]  阅读(4)  评论(0编辑  收藏  举报