C++ 自己动手实现简单的文件操作 (2023.6.23)

C++ 自己动手实现简单的文件操作 2023.6.23

  • 引言
  • 1、文件简介
  • 2、各式各样的文件格式
    • 2.1 不同类型文件的扩展名
      • 2.1.1 文本文件
      • 2.1.2 数据文件
      • 2.1.3 音频文件
      • 2.1.4 视频文件
      • 2.1.5 电子书文件
      • 2.1.6 3D图像文件
      • 2.1.7 位图文件
      • 2.1.8 矢量图文件
      • 2.1.9 相机原始文件
      • 2.1.10 页面布局文件
      • 2.1.11 电子表格文件
      • 2.1.12 数据库文件
      • 2.1.13 可执行文件
      • 2.1.14 游戏文件
      • 2.1.15 CAD文件
      • 2.1.16 地图信息文件
      • 2.1.17 网页文件
      • 2.1.18 插件文件
      • 2.1.19 字体文件
      • 2.1.20 系统文件
      • 2.1.21 配置文件
      • 2.1.22 编码文件
      • 2.1.23 加密文件
      • 2.1.24 压缩文件
      • 2.1.25 镜像文件
      • 2.1.26 编程文件
      • 2.1.27 备份文件
      • 2.1.28 临时文件
      • 2.1.29 其他文件
    • 2.2 不同类型的软件
      • 2.2.1 视频软件
      • 2.2.2 浏览器
      • 2.2.3 办公软件
      • 2.2.4 音乐软件
      • 2.2.5 游戏娱乐
      • 2.2.6 图形图像
      • 2.2.7 系统工具
      • 2.2.8 压缩刻录
      • 2.2.9 阅读翻译
      • 2.2.10 网络应用
      • 2.2.11 教育学习
      • 2.2.12 编程开发
  • 3、C++代码实现简单文件操作
    • 3.1 文件字符串操作
      • 3.1.1 计算文件字符串的长度
        • 3.1.1.1 自己写(getStrLen)
        • 3.1.1.2 官方(getStrLen_Official)
      • 3.1.2 获取文件字符串中的文件后缀名
        • 3.1.2.1 自己写(getFileSuffixFromStr)
        • 3.1.2.2 官方(getFileSuffixFromStr_Official)
      • 3.1.3 获取文件字符串中的文件名
        • 3.1.3.1 自己写(getFileNameFromStr)
        • 3.1.3.2 官方(getFileNameFromStr_Official)
      • 3.1.4 获取文件字符串中的文件路径
        • 3.1.4.1 自己写(getFilePath)
        • 3.1.4.2 自己写+官方(getFilePath_Official)
        • 3.1.4.3 官方(GetPathDir_Official)
    • 3.2 文件和文件夹
      • 3.2.1 判断文件夹是否存在(isFileExist_Official)
      • 3.2.2 判断文件是否存在
      • 3.2.3 创建单个文件夹
      • 3.2.4 创建多级文件目录(CreateMultiLevel_Official)
      • 3.2.5 读取文本文件(readTxt)
      • 3.2.6 写入文本文件(write_file)
      • 3.2.7 写入二进制文本文件
        • 3.2.7.1 基于FILE类(write_file)
        • 3.2.7.2 基于ofstream 类(write_file_Official)
      • 3.2.8 读取二进制文本文件(readFileBuffer)
    • 3.3 完整代码及测试运行
      • 3.3.1 代码文件(main.cpp)
      • 3.3.2 运行结果
      • 3.3.3 main.cpp(部分注释)运行
  • 4、总结

引言

        在日常的学习和工作当中,大家每天都会接触大量的文件和文件夹,或多或少都会打开文件浏览读取文件写入文件,你可能会编写Word报告、编辑Excel报表、制作PPT幻灯片、编辑图片、视频、音频,你可能会开启视频直播、开启在线会议、玩在线游戏、听在线音乐、看股市动态、在线教学或上课、在网上购物众多场景都离不开用户加密、缓存文件、文件流、日志记录、历史数据和操作备份,当然很多使用者并不关心其中的缓存文件和日志记录,有需要的时候更多只是进行了真实体验、完成了整个服务过程,后续的用户反馈和数据迁移、找回和备份等仅仅是个人利益收到损失时才会想到联系客服在后台服务端获取历史账单和交易明细等

        大家往往都要依赖市面上成熟的编辑软件,当然在现代如此强大的Windows、Linux、Unix、MacOS等操作系统生态环境中,蕴含着五花八门、专精特新的应用市场和各类软件,如Microsoft Store腾讯电脑管家360软件管家等等,各类应用厂商都竞相退出具有自己特色的安全绿色软件,尝试形成自己的软件阵营针对某个领域发布一系列、一整套、一体化的软件包、软件产品、软件使用手册、二次开发SDK和API调用说明,在整个过程中需要依赖于国际上开放的数据标准兼容通用的数据格式扩展自定义、符号特定应用的数据类型并进行大力推广。

1、文件简介

        所谓文件,它是各种形式的信息记录,涵盖到政治、历史、法律、经济、社会、工业、农业生产等多个方面,可以是规范、标准、政策、法规,也可以是研究报告、学术文章、历史记载等等,这些不同类型的文件往往以千姿百态的形式加以保存,也就形成了适应于人类社会发展和实际生产需要的数据格式,针对多样化的数据格式,由不同的解析方式来打开和浏览,以规范化的组织方式来保存。

C++ 自己动手实现简单的文件操作 (2023.6.23)_第1张图片
文件
C++ 自己动手实现简单的文件操作 (2023.6.23)_第2张图片
文件夹

        文件夹指的是在很多年商业或事业活动中,为了整齐规范地保存文件,用夹子来保存和管理符合某些特性的零碎文件和文件集合,由现实社会中的公文包过渡为计算机软件中的虚拟目录。

2、各式各样的文件格式

        文件格式与文件类型密切相关,常用的文件类型如下:
C++ 自己动手实现简单的文件操作 (2023.6.23)_第3张图片

2.1 不同类型文件的扩展名

        下面简单查看一下各类文件的图标、扩展名及说明信息,以便大家有所了解,感叹文件类型的繁华各异。

2.1.1 文本文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第4张图片

2.1.2 数据文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第5张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第6张图片

2.1.3 音频文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第7张图片

2.1.4 视频文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第8张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第9张图片

2.1.5 电子书文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第10张图片

2.1.6 3D图像文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第11张图片

2.1.7 位图文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第12张图片

2.1.8 矢量图文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第13张图片

2.1.9 相机原始文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第14张图片

2.1.10 页面布局文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第15张图片

2.1.11 电子表格文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第16张图片

2.1.12 数据库文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第17张图片

2.1.13 可执行文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第18张图片

2.1.14 游戏文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第19张图片

2.1.15 CAD文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第20张图片

2.1.16 地图信息文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第21张图片

2.1.17 网页文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第22张图片

2.1.18 插件文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第23张图片

2.1.19 字体文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第24张图片

2.1.20 系统文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第25张图片

2.1.21 配置文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第26张图片

2.1.22 编码文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第27张图片

2.1.23 加密文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第28张图片

2.1.24 压缩文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第29张图片

2.1.25 镜像文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第30张图片

2.1.26 编程文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第31张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第32张图片

2.1.27 备份文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第33张图片

2.1.28 临时文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第34张图片

2.1.29 其他文件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第35张图片

2.2 不同类型的软件

        对于各种类型的文件格式,自然有相对应的软件厂商开发对应的软件与之适配、兼容,下面按照不同类型来介绍一些有用且流行的软件。

2.2.1 视频软件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第36张图片

2.2.2 浏览器

C++ 自己动手实现简单的文件操作 (2023.6.23)_第37张图片

2.2.3 办公软件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第38张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第39张图片

2.2.4 音乐软件

C++ 自己动手实现简单的文件操作 (2023.6.23)_第40张图片

2.2.5 游戏娱乐

C++ 自己动手实现简单的文件操作 (2023.6.23)_第41张图片

2.2.6 图形图像

C++ 自己动手实现简单的文件操作 (2023.6.23)_第42张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第43张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第44张图片

2.2.7 系统工具

C++ 自己动手实现简单的文件操作 (2023.6.23)_第45张图片

2.2.8 压缩刻录

C++ 自己动手实现简单的文件操作 (2023.6.23)_第46张图片

2.2.9 阅读翻译

C++ 自己动手实现简单的文件操作 (2023.6.23)_第47张图片

2.2.10 网络应用

C++ 自己动手实现简单的文件操作 (2023.6.23)_第48张图片

2.2.11 教育学习

C++ 自己动手实现简单的文件操作 (2023.6.23)_第49张图片

2.2.12 编程开发

C++ 自己动手实现简单的文件操作 (2023.6.23)_第50张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第51张图片
C++ 自己动手实现简单的文件操作 (2023.6.23)_第52张图片

3、C++代码实现简单文件操作

        下面就一些简单的文件操作(文件字符串和文件夹文本文件读写)来用高级编程语言C++进行实现,包括自己写的部分和官方模板库中的函数调用,希望大家不必重复造轮子,但也应知其所以然,夯实知识基础,可随心所欲修改,切勿受制于人代码本身没有价值,但其中蕴含的思想和理念会在编译运行后加以体现,进而展现特定的功能,实现必要的目的进而满足学习、科研和工作的需求,望大家都能掌握自主可控的源码,大力推进核心软件国产化的发展趋势。

3.1 文件字符串操作

3.1.1 计算文件字符串的长度

3.1.1.1 自己写(getStrLen)

size_t getStrLen(std::string str)//自定义函数计算字符串的长度
{
	char* temp = &str[0];
	size_t len = 0;
	while (*temp != '\0')
	{
		len++;
		temp++;
	}
	return len;
}

3.1.1.2 官方(getStrLen_Official)

size_t getStrLen_Official(std::string str)//调用官方函数计算字符串的长度
{
	return str.size();
}

3.1.2 获取文件字符串中的文件后缀名

3.1.2.1 自己写(getFileSuffixFromStr)

std::string getFileSuffixFromStr(std::string inputFileName)//自定义函数获取文件的扩展名
{
	std::string suffix = "";
	bool isLastDot = false;
	char* temp = &inputFileName[0];
	while (*temp != '\0')
	{
		if (*temp == '.')
		{
			isLastDot = true;
			suffix = "";
		}
		if (isLastDot)
			suffix += *temp;
		temp++;
	}
	return suffix;
}

3.1.2.2 官方(getFileSuffixFromStr_Official)

std::string getFileSuffixFromStr_Official(std::string inputFileName)//调用官方函数获取文件的扩展名
{
	std::string suffix = "";
	size_t lastDotPos = inputFileName.find_last_of('.');
	size_t len = getStrLen_Official(inputFileName);

	if (lastDotPos >= 0 && len > 1 && lastDotPos < len - 1)
	{
		for (size_t i = lastDotPos; i<len; i++)
			suffix += inputFileName[i];
	}

	return suffix;
}

3.1.3 获取文件字符串中的文件名

3.1.3.1 自己写(getFileNameFromStr)

std::string getFileNameFromStr(std::string inputFileName, bool isWithSuffix)//自定义函数获取字符串中的文件名
{
	std::string filename = "", suffix = getFileSuffixFromStr_Official(inputFileName);
	size_t lastDotPos = inputFileName.find_last_of('.'),
		len = getStrLen(inputFileName),
		lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < len)
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos >= 0 && lastDotPos >= 0 && lastDotPos > lastXiePos + 1)
	{
		for (size_t i = lastXiePos + 1; i<lastDotPos; i++)
			filename += inputFileName[i];
	}

	if (!isWithSuffix)
		return filename;
	else
		return filename + suffix;
}

3.1.3.2 官方(getFileNameFromStr_Official)

std::string getFileNameFromStr_Official(std::string inputFileName, bool isWithSuffix)//调用官方函数获取字符串中的文件名
{
	std::string filename = "", suffix = getFileSuffixFromStr_Official(inputFileName);
	size_t lastDotPos = inputFileName.find_last_of('.'),
		len = getStrLen_Official(inputFileName),
		lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < len)
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos >= 0 && lastDotPos >= 0 && lastDotPos > lastXiePos + 1)
	{
		for (size_t i = lastXiePos + 1; i<lastDotPos; i++)
			filename += inputFileName[i];
	}
	if (!isWithSuffix)
		return filename;
	else
		return filename + suffix;
}

3.1.4 获取文件字符串中的文件路径

3.1.4.1 自己写(getFilePath)

std::string getFilePath(std::string inputFileName)//自定义函数获取字符串中的文件路径
{
	std::string filepath = "";
	size_t len = 0, lastXiePos = -1;
	char* temp = &inputFileName[0];
	while (*temp != '\0')
	{
		char a = *temp;
		if (a == '\\' || a == '/')
			lastXiePos = len;
		temp++;
		len++;
	}

	temp = &inputFileName[0];
	len = 0;
	while (len < lastXiePos)
	{
		filepath += *temp;
		temp++;
		len++;
	}
	return filepath;
}

3.1.4.2 自己写+官方(getFilePath_Official)

std::string getFilePath_Official(std::string inputFileName)//自定义+官方函数获取字符串中的文件路径
{
	std::string filepath = "";
	size_t lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < inputFileName.size())
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos > 0)
	{
		for (int i = 0; i<lastXiePos; i++)
			filepath += inputFileName[i];
	}
	return filepath;
}

3.1.4.3 官方(GetPathDir_Official)

std::string GetPathDir_Official(string filePath)//调用官方函数得到文件路径的目录
{
	std::string dirPath = filePath;
	size_t p = filePath.find_last_of('\\'), p1 = filePath.find_last_of('/');
	if (p != -1 && p < filePath.size())
	{
		dirPath.erase(p);
		return dirPath;
	}
	else if (p1 != -1 && p1 < filePath.size())
	{
		dirPath.erase(p1);
		return dirPath;
	}
	return dirPath;
}

3.2 文件和文件夹

3.2.1 判断文件夹是否存在(isFileExist_Official)

bool isFileExist_Official(std::string dir) //判断文件或目录是否存在
{
	if (_access(dir.c_str(), 00) == 0)
	{
		return true;
	}
	else
		return false;
}

3.2.2 判断文件是否存在

bool isExistFileName(std::string filename) //判断文件是否存在
{
	std::fstream _file;
	_file.open(filename, std::ios::in);
	if (!_file)
		return false;
	else
		return true;
}

3.2.3 创建单个文件夹

bool mkdir_Official(std::string dir) //创建单个目录
{
	bool res = false;
	if (_mkdir(dir.c_str()))
		res = true;
	return res;
}

3.2.4 创建多级文件目录(CreateMultiLevel_Official)

void CreateMultiLevel_Official(std::string dir)//创建多级目录
{
	if (_access(dir.c_str(), 00) == 0)
	{
		return;
	}

	list <string> dirList;
	dirList.push_front(dir);

	string curDir = GetPathDir_Official(dir);
	while (curDir != dir)
	{
		if (_access(curDir.c_str(), 00) == 0)
		{
			break;
		}

		dirList.push_front(curDir);

		dir = curDir;
		curDir = GetPathDir_Official(dir);
	}

	for (auto it : dirList)
	{
		_mkdir(it.c_str());
	}
}

3.2.5 读取文本文件(readTxt)

std::string readTxt(std::string filenamewithFolder, bool isWithEnter = false) //读取文本文件
{
	ifstream infile(filenamewithFolder);
	std::string buffer = "", res = "";
	while (getline(infile, buffer))
		if (buffer != "")
			res += buffer + (isWithEnter ? "\n" : "");
	infile.close();
	return res;
}

3.2.6 写入文本文件(write_file)

bool write_file(std::string filename, std::string content)//写入文本文件
{
	bool res = false;
	std::ofstream ofs;
	ofs.open(filename, std::ios::out | std::ios::trunc);
	if (ofs)
	{
		const char *Content = &content[0];
		ofs << Content;
		ofs.close();
		res = true;
	}
	return res;
}

3.2.7 写入二进制文本文件

3.2.7.1 基于FILE类(write_file)

bool write_file(const char* filename, const char* buf, unsigned long buf_len) //将字符串以二进制内容写入文件
{
	FILE* f1 = fopen(filename, "wb");
	if (!f1)
	{
		printf("can`t open file: %s\n", filename);
		return false;
	}
	int glb_len = buf_len;
	if (glb_len != fwrite(buf, 1, glb_len, f1))
	{
		printf("write file %s error\n", filename);
		return false;
	}
	fclose(f1);
	return true;
}

3.2.7.2 基于ofstream 类(write_file_Official)

bool write_file_Official(const char* filename, const char* buf) //将字符串以二进制内容写入文件
{
	bool res = false;
	std::ofstream ofs;
	ofs.open(filename, std::ios::out | std::ios::binary);
	if (ofs)
	{
		const char *Content = buf;
		ofs << Content;
		ofs.close();
		res = true;
	}
	return res;
}

3.2.8 读取二进制文本文件(readFileBuffer)

char* readFileBuffer(std::string input, long& fsize) //读取二进制文本文件得到字符串
{
	FILE* f = fopen(input.c_str(), "rb");
	if (!f)
	{
		printf("can`t open file: %s\n", input.c_str());
		return NULL;
	}
	fseek(f, 0, SEEK_END);
	fsize = ftell(f);
	fseek(f, 0, SEEK_SET);
	char * buffer = new char[fsize + 1];
	if (fsize != fread(buffer, 1, fsize, f))
	{
		printf("read file %s error\n", input.c_str());
		fclose(f);
		delete[]buffer;
		return NULL;
	}
	buffer[fsize] = 0;
	fclose(f);
	return buffer;
}

3.3 完整代码及测试运行

3.3.1 代码文件(main.cpp)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


size_t getStrLen(std::string str)//自定义函数计算字符串的长度
{
	char* temp = &str[0];
	size_t len = 0;
	while (*temp != '\0')
	{
		len++;
		temp++;
	}
	return len;
}

size_t getStrLen_Official(std::string str)//调用官方函数计算字符串的长度
{
	return str.size();
}

std::string getFileSuffixFromStr(std::string inputFileName)//自定义函数获取文件的扩展名
{
	std::string suffix = "";
	bool isLastDot = false;
	char* temp = &inputFileName[0];
	while (*temp != '\0')
	{
		if (*temp == '.')
		{
			isLastDot = true;
			suffix = "";
		}
		if (isLastDot)
			suffix += *temp;
		temp++;
	}
	return suffix;
}

std::string getFileSuffixFromStr_Official(std::string inputFileName)//调用官方函数获取文件的扩展名
{
	std::string suffix = "";
	size_t lastDotPos = inputFileName.find_last_of('.');
	size_t len = getStrLen_Official(inputFileName);

	if (lastDotPos >= 0 && len > 1 && lastDotPos < len - 1)
	{
		for (size_t i = lastDotPos; i<len; i++)
			suffix += inputFileName[i];
	}

	return suffix;
}

std::string getFileNameFromStr(std::string inputFileName, bool isWithSuffix)//自定义函数获取字符串中的文件名
{
	std::string filename = "", suffix = getFileSuffixFromStr_Official(inputFileName);
	size_t lastDotPos = inputFileName.find_last_of('.'),
		len = getStrLen(inputFileName),
		lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < len)
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos >= 0 && lastDotPos >= 0 && lastDotPos > lastXiePos + 1)
	{
		for (size_t i = lastXiePos + 1; i<lastDotPos; i++)
			filename += inputFileName[i];
	}

	if (!isWithSuffix)
		return filename;
	else
		return filename + suffix;
}

std::string getFileNameFromStr_Official(std::string inputFileName, bool isWithSuffix)//调用官方函数获取字符串中的文件名
{
	std::string filename = "", suffix = getFileSuffixFromStr_Official(inputFileName);
	size_t lastDotPos = inputFileName.find_last_of('.'),
		len = getStrLen_Official(inputFileName),
		lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < len)
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos >= 0 && lastDotPos >= 0 && lastDotPos > lastXiePos + 1)
	{
		for (size_t i = lastXiePos + 1; i<lastDotPos; i++)
			filename += inputFileName[i];
	}
	if (!isWithSuffix)
		return filename;
	else
		return filename + suffix;
}

std::string getFilePath(std::string inputFileName)//自定义函数获取字符串中的文件路径
{
	std::string filepath = "";
	size_t len = 0, lastXiePos = -1;
	char* temp = &inputFileName[0];
	while (*temp != '\0')
	{
		char a = *temp;
		if (a == '\\' || a == '/')
			lastXiePos = len;
		temp++;
		len++;
	}

	temp = &inputFileName[0];
	len = 0;
	while (len < lastXiePos)
	{
		filepath += *temp;
		temp++;
		len++;
	}
	return filepath;
}

std::string getFilePath_Official(std::string inputFileName)//自定义+官方函数获取字符串中的文件路径
{
	std::string filepath = "";
	size_t lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < inputFileName.size())
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos > 0)
	{
		for (int i = 0; i<lastXiePos; i++)
			filepath += inputFileName[i];
	}
	return filepath;
}

std::string GetPathDir_Official(string filePath)//调用官方函数得到文件路径的目录
{
	std::string dirPath = filePath;
	size_t p = filePath.find_last_of('\\'), p1 = filePath.find_last_of('/');
	if (p != -1 && p < filePath.size())
	{
		dirPath.erase(p);
		return dirPath;
	}
	else if (p1 != -1 && p1 < filePath.size())
	{
		dirPath.erase(p1);
		return dirPath;
	}
	return dirPath;
}

bool mkdir_Official(std::string dir) //创建单个目录
{
	bool res = false;
	if (_mkdir(dir.c_str()))
		res = true;
	return res;
}

void CreateMultiLevel_Official(std::string dir)//创建多级目录
{
	if (_access(dir.c_str(), 00) == 0)
	{
		return;
	}

	list <string> dirList;
	dirList.push_front(dir);

	string curDir = GetPathDir_Official(dir);
	while (curDir != dir)
	{
		if (_access(curDir.c_str(), 00) == 0)
		{
			break;
		}

		dirList.push_front(curDir);

		dir = curDir;
		curDir = GetPathDir_Official(dir);
	}

	for (auto it : dirList)
	{
		_mkdir(it.c_str());
	}
}

bool isFileExist_Official(std::string dir) //判断文件或目录是否存在
{
	if (_access(dir.c_str(), 00) == 0)
	{
		return true;
	}
	else
		return false;
}

bool isExistFileName(std::string filename) //判断文件是否存在
{
	std::fstream _file;
	_file.open(filename, std::ios::in);
	if (!_file)
		return false;
	else
		return true;
}

bool write_file(std::string filename, std::string content)//写入文本文件
{
	bool res = false;
	std::ofstream ofs;
	ofs.open(filename, std::ios::out | std::ios::trunc);
	if (ofs)
	{
		const char *Content = &content[0];
		ofs << Content;
		ofs.close();
		res = true;
	}
	return res;
}

std::string readTxt(std::string filenamewithFolder, bool isWithEnter = false) //读取文本文件
{
	ifstream infile(filenamewithFolder);
	std::string buffer = "", res = "";
	while (getline(infile, buffer))
		if (buffer != "")
			res += buffer + (isWithEnter ? "\n" : "");
	infile.close();
	return res;
}

bool write_file(const char* filename, const char* buf, unsigned long buf_len) //将字符串以二进制内容写入文件
{
	FILE* f1 = fopen(filename, "wb");
	if (!f1)
	{
		printf("can`t open file: %s\n", filename);
		return false;
	}
	int glb_len = buf_len;
	if (glb_len != fwrite(buf, 1, glb_len, f1))
	{
		printf("write file %s error\n", filename);
		return false;
	}
	fclose(f1);
	return true;
}

bool write_file_Official(const char* filename, const char* buf) //将字符串以二进制内容写入文件
{
	bool res = false;
	std::ofstream ofs;
	ofs.open(filename, std::ios::out | std::ios::binary);
	if (ofs)
	{
		const char *Content = buf;
		ofs << Content;
		ofs.close();
		res = true;
	}
	return res;
}

char* readFileBuffer(std::string input, long& fsize) //读取二进制文本文件得到字符串
{
	FILE* f = fopen(input.c_str(), "rb");
	if (!f)
	{
		printf("can`t open file: %s\n", input.c_str());
		return NULL;
	}
	fseek(f, 0, SEEK_END);
	fsize = ftell(f);
	fseek(f, 0, SEEK_SET);
	char * buffer = new char[fsize + 1];
	if (fsize != fread(buffer, 1, fsize, f))
	{
		printf("read file %s error\n", input.c_str());
		fclose(f);
		delete[]buffer;
		return NULL;
	}
	buffer[fsize] = 0;
	fclose(f);
	return buffer;
}

void Test_fileStr(std::string fileStr)
{
	std::cout << "计算字符串长度(自定义)为:" << getStrLen(fileStr) << std::endl;
	std::cout << "计算字符串长度(官方)为:" << getStrLen_Official(fileStr) << std::endl;
	std::cout << "获取扩展名(自定义)为:" << getFileSuffixFromStr(fileStr) << std::endl;
	std::cout << "获取扩展名(官方)为:" << getFileSuffixFromStr_Official(fileStr) << std::endl;
	std::cout << "获取不带扩展名的文件名(自定义)为:" << getFileNameFromStr(fileStr, false) << std::endl;
	std::cout << "获取不带扩展名的文件名(官方)为:" << getFileNameFromStr_Official(fileStr, false) << std::endl;
	std::cout << "获取带扩展名的文件名(自定义)为:" << getFileNameFromStr(fileStr, true) << std::endl;
	std::cout << "获取带扩展名的文件名(官方)为:" << getFileNameFromStr_Official(fileStr, true) << std::endl;
	std::cout << "获取文件路径(自定义)为:" << getFilePath(fileStr) << std::endl;
	std::cout << "获取文件路径(自定义+官方)为:" << getFilePath_Official(fileStr) << std::endl;
	std::cout << "获取文件路径(官方)为:" << GetPathDir_Official(fileStr) << std::endl;
}

void Test_fileFolder()
{
	mkdir_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\ceshi2");
	CreateMultiLevel_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\ceshi\\temp\\nihao");
	string fileName = "123.txt", content = "2023年6月23日 星期五 农历五月初六\n \
        今天是端午节❤️❤️❤️\n \
		亲爱的孟营\n \
		北京热吗?\n \
		你最近过得怎么样?\n \
		希望我们都好好的\n \
		青春年华甚是美好,可时光不再,佳人在水一方,时常感慨曾经的日子\n \
        多年后愿再见到你仍然幸运可爱,落落大方\n \
        致我们终将逝去的青春 \n \
        ✨";
	write_file(fileName, content);
	if (isFileExist_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\"))
	{
		std::cout << "文件夹存在" << std::endl;
	}
	else
	{
		std::cout << "文件夹不存在" << std::endl;
	}
	if (!isExistFileName("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\1233.txt"))
	{
		std::cout << "文件不存在" << std::endl;
	}
	if (isFileExist_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\123.txt"))
	{
		std::cout << "文件存在" << std::endl;
		std::cout << readTxt("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\123.txt",true) << std::endl;
	}
	else
	{
		std::cout << "文件不存在" << std::endl;
	}
	string filename_bin = "456.txt", filename_bin2 = "789.txt",content_bin="{\n\r\t\"year\": 2023, \n\r\t\"month\": 6,\n\r\t\"day\":23\n\r\t} ", content_bin2 = "asdfjasofjasdiof132r234323r sdfa  sdafsdf a sdfsda ";
	write_file(filename_bin.c_str(), content_bin.data(), content_bin.size());
	write_file_Official(filename_bin2.c_str(), content_bin2.c_str());


	/*long fsize = 0;
	char * buffer = readFileBuffer(filename_bin, fsize);
	if (buffer)
	{
		std::cout << "读取二进制文本文件内容如下:" << std::endl;
		std::cout << buffer<
}

int main(int argc, char *argv[])
{
	std::cout << "**********************文件字符串测试开始!**********************" << std::endl;
	std::string fileStr = "E:\\jing_zhong\\ConsoleApplication1\\ConsoleApplication1\\main.cpp";
	fileStr = "C:/Users/Lenovo/source/repos/ConsoleApplication1/x64/Release/test.docx";
	Test_fileStr(fileStr);
	std::cout << "**********************文件字符串测试结束!**********************" << std::endl;

	std::cout << "**********************文件夹和文件读写测试开始!**********************" << std::endl;
	Test_fileFolder();
	std::cout << "**********************文件夹和文件读写测试结束!**********************" << std::endl;
	return 0;
}

3.3.2 运行结果

        运行后可以在控制台看到文件字符串的信息,有文件名、扩展名和文件路径,同时可看到文件和文件夹的判断结果,文本文件的写入和读取、二进制文本文件的写入及读取结果,当然代码匆匆整理而来,难免存在疏漏,请各位多多指教,如有不妥之处,还望见谅

C++ 自己动手实现简单的文件操作 (2023.6.23)_第53张图片
运行前
C++ 自己动手实现简单的文件操作 (2023.6.23)_第54张图片
运行后
C++ 自己动手实现简单的文件操作 (2023.6.23)_第55张图片
123.txt
C++ 自己动手实现简单的文件操作 (2023.6.23)_第56张图片
456.txt
C++ 自己动手实现简单的文件操作 (2023.6.23)_第57张图片
789.txt

3.3.3 main.cpp(部分注释)运行

main.cpp文件

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


size_t getStrLen(std::string str)//自定义函数计算字符串的长度
{
	char* temp = &str[0];
	size_t len = 0;
	while (*temp != '\0')
	{
		len++;
		temp++;
	}
	return len;
}

size_t getStrLen_Official(std::string str)//调用官方函数计算字符串的长度
{
	return str.size();
}

std::string getFileSuffixFromStr(std::string inputFileName)//自定义函数获取文件的扩展名
{
	std::string suffix = "";
	bool isLastDot = false;
	char* temp = &inputFileName[0];
	while (*temp != '\0')
	{
		if (*temp == '.')
		{
			isLastDot = true;
			suffix = "";
		}
		if (isLastDot)
			suffix += *temp;
		temp++;
	}
	return suffix;
}

std::string getFileSuffixFromStr_Official(std::string inputFileName)//调用官方函数获取文件的扩展名
{
	std::string suffix = "";
	size_t lastDotPos = inputFileName.find_last_of('.');
	size_t len = getStrLen_Official(inputFileName);

	if (lastDotPos >= 0 && len > 1 && lastDotPos < len - 1)
	{
		for (size_t i = lastDotPos; i<len; i++)
			suffix += inputFileName[i];
	}

	return suffix;
}

std::string getFileNameFromStr(std::string inputFileName, bool isWithSuffix)//自定义函数获取字符串中的文件名
{
	std::string filename = "", suffix = getFileSuffixFromStr_Official(inputFileName);
	size_t lastDotPos = inputFileName.find_last_of('.'),
		len = getStrLen(inputFileName),
		lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < len)
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos >= 0 && lastDotPos >= 0 && lastDotPos > lastXiePos + 1)
	{
		for (size_t i = lastXiePos + 1; i<lastDotPos; i++)
			filename += inputFileName[i];
	}

	if (!isWithSuffix)
		return filename;
	else
		return filename + suffix;
}

std::string getFileNameFromStr_Official(std::string inputFileName, bool isWithSuffix)//调用官方函数获取字符串中的文件名
{
	std::string filename = "", suffix = getFileSuffixFromStr_Official(inputFileName);
	size_t lastDotPos = inputFileName.find_last_of('.'),
		len = getStrLen_Official(inputFileName),
		lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < len)
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos >= 0 && lastDotPos >= 0 && lastDotPos > lastXiePos + 1)
	{
		for (size_t i = lastXiePos + 1; i<lastDotPos; i++)
			filename += inputFileName[i];
	}
	if (!isWithSuffix)
		return filename;
	else
		return filename + suffix;
}

std::string getFilePath(std::string inputFileName)//自定义函数获取字符串中的文件路径
{
	std::string filepath = "";
	size_t len = 0, lastXiePos = -1;
	char* temp = &inputFileName[0];
	while (*temp != '\0')
	{
		char a = *temp;
		if (a == '\\' || a == '/')
			lastXiePos = len;
		temp++;
		len++;
	}

	temp = &inputFileName[0];
	len = 0;
	while (len < lastXiePos)
	{
		filepath += *temp;
		temp++;
		len++;
	}
	return filepath;
}

std::string getFilePath_Official(std::string inputFileName)//自定义+官方函数获取字符串中的文件路径
{
	std::string filepath = "";
	size_t lastXiePos = -1,
		lastXiePos1 = inputFileName.find_last_of('/'),
		lastXiePos2 = inputFileName.find_last_of('\\');
	if (lastXiePos1 > 0 && lastXiePos1 < inputFileName.size())
		lastXiePos = lastXiePos1;
	else if (lastXiePos2 > 0)
		lastXiePos = lastXiePos2;

	if (lastXiePos > 0)
	{
		for (int i = 0; i<lastXiePos; i++)
			filepath += inputFileName[i];
	}
	return filepath;
}

std::string GetPathDir_Official(string filePath)//调用官方函数得到文件路径的目录
{
	std::string dirPath = filePath;
	size_t p = filePath.find_last_of('\\'), p1 = filePath.find_last_of('/');
	if (p != -1 && p < filePath.size())
	{
		dirPath.erase(p);
		return dirPath;
	}
	else if (p1 != -1 && p1 < filePath.size())
	{
		dirPath.erase(p1);
		return dirPath;
	}
	return dirPath;
}

bool mkdir_Official(std::string dir) //创建单个目录
{
	bool res = false;
	if (_mkdir(dir.c_str()))
		res = true;
	return res;
}

void CreateMultiLevel_Official(std::string dir)//创建多级目录
{
	if (_access(dir.c_str(), 00) == 0)
	{
		return;
	}

	list <string> dirList;
	dirList.push_front(dir);

	string curDir = GetPathDir_Official(dir);
	while (curDir != dir)
	{
		if (_access(curDir.c_str(), 00) == 0)
		{
			break;
		}

		dirList.push_front(curDir);

		dir = curDir;
		curDir = GetPathDir_Official(dir);
	}

	for (auto it : dirList)
	{
		_mkdir(it.c_str());
	}
}

bool isFileExist_Official(std::string dir) //判断文件或目录是否存在
{
	if (_access(dir.c_str(), 00) == 0)
	{
		return true;
	}
	else
		return false;
}

bool isExistFileName(std::string filename) //判断文件是否存在
{
	std::fstream _file;
	_file.open(filename, std::ios::in);
	if (!_file)
		return false;
	else
		return true;
}

bool write_file(std::string filename, std::string content)//写入文本文件
{
	bool res = false;
	std::ofstream ofs;
	ofs.open(filename, std::ios::out | std::ios::trunc);
	if (ofs)
	{
		const char *Content = &content[0];
		ofs << Content;
		ofs.close();
		res = true;
	}
	return res;
}

std::string readTxt(std::string filenamewithFolder, bool isWithEnter = false) //读取文本文件
{
	ifstream infile(filenamewithFolder);
	std::string buffer = "", res = "";
	while (getline(infile, buffer))
		if (buffer != "")
			res += buffer + (isWithEnter ? "\n" : "");
	infile.close();
	return res;
}

bool write_file(const char* filename, const char* buf, unsigned long buf_len) //将字符串以二进制内容写入文件
{
	FILE* f1 = fopen(filename, "wb");
	if (!f1)
	{
		printf("can`t open file: %s\n", filename);
		return false;
	}
	int glb_len = buf_len;
	if (glb_len != fwrite(buf, 1, glb_len, f1))
	{
		printf("write file %s error\n", filename);
		return false;
	}
	fclose(f1);
	return true;
}

bool write_file_Official(const char* filename, const char* buf) //将字符串以二进制内容写入文件
{
	bool res = false;
	std::ofstream ofs;
	ofs.open(filename, std::ios::out | std::ios::binary);
	if (ofs)
	{
		const char *Content = buf;
		ofs << Content;
		ofs.close();
		res = true;
	}
	return res;
}

char* readFileBuffer(std::string input, long& fsize) //读取二进制文本文件得到字符串
{
	FILE* f = fopen(input.c_str(), "rb");
	if (!f)
	{
		printf("can`t open file: %s\n", input.c_str());
		return NULL;
	}
	fseek(f, 0, SEEK_END);
	fsize = ftell(f);
	fseek(f, 0, SEEK_SET);
	char * buffer = new char[fsize + 1];
	if (fsize != fread(buffer, 1, fsize, f))
	{
		printf("read file %s error\n", input.c_str());
		fclose(f);
		delete[]buffer;
		return NULL;
	}
	buffer[fsize] = 0;
	fclose(f);
	return buffer;
}

void Test_fileStr(std::string fileStr)
{
	std::cout << "计算字符串长度(自定义)为:" << getStrLen(fileStr) << std::endl;
	std::cout << "计算字符串长度(官方)为:" << getStrLen_Official(fileStr) << std::endl;
	std::cout << "获取扩展名(自定义)为:" << getFileSuffixFromStr(fileStr) << std::endl;
	std::cout << "获取扩展名(官方)为:" << getFileSuffixFromStr_Official(fileStr) << std::endl;
	std::cout << "获取不带扩展名的文件名(自定义)为:" << getFileNameFromStr(fileStr, false) << std::endl;
	std::cout << "获取不带扩展名的文件名(官方)为:" << getFileNameFromStr_Official(fileStr, false) << std::endl;
	std::cout << "获取带扩展名的文件名(自定义)为:" << getFileNameFromStr(fileStr, true) << std::endl;
	std::cout << "获取带扩展名的文件名(官方)为:" << getFileNameFromStr_Official(fileStr, true) << std::endl;
	std::cout << "获取文件路径(自定义)为:" << getFilePath(fileStr) << std::endl;
	std::cout << "获取文件路径(自定义+官方)为:" << getFilePath_Official(fileStr) << std::endl;
	std::cout << "获取文件路径(官方)为:" << GetPathDir_Official(fileStr) << std::endl;
}

void Test_fileFolder()
{
	mkdir_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\ceshi2");
	CreateMultiLevel_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\ceshi\\temp\\nihao");
	string fileName = "123.txt", content = "2023年6月23日 星期五 农历五月初六\n \
        今天是端午节❤️❤️❤️\n \
		亲爱的孟营\n \
		北京热吗?\n \
		你最近过得怎么样?\n \
		希望我们都好好的\n \
		青春年华甚是美好,可时光不再,佳人在水一方,时常感慨曾经的日子\n \
        多年后愿再见到你仍然幸运可爱,落落大方\n \
        致我们终将逝去的青春 \n \
        ✨";
	write_file(fileName, content);
	if (isFileExist_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\"))
	{
		std::cout << "文件夹存在" << std::endl;
	}
	else
	{
		std::cout << "文件夹不存在" << std::endl;
	}
	if (!isExistFileName("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\1233.txt"))
	{
		std::cout << "文件不存在" << std::endl;
	}
	/*if (isFileExist_Official("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\123.txt"))
	{
		std::cout << "文件存在" << std::endl;
		std::cout << readTxt("E:\\jing_zhong\\ConsoleApplication3\\ConsoleApplication3\\123.txt",true) << std::endl;
	}
	else
	{
		std::cout << "文件不存在" << std::endl;
	}*/
	string filename_bin = "456.txt", filename_bin2 = "789.txt",content_bin="{\n\r\t\"year\": 2023, \n\r\t\"month\": 6,\n\r\t\"day\":23\n\r\t} ", content_bin2 = "asdfjasofjasdiof132r234323r sdfa  sdafsdf a sdfsda ";
	write_file(filename_bin.c_str(), content_bin.data(), content_bin.size());
	write_file_Official(filename_bin2.c_str(), content_bin2.c_str());


	long fsize = 0;
	char * buffer = readFileBuffer(filename_bin, fsize);
	if (buffer)
	{
		std::cout << "读取二进制文本文件内容如下:" << std::endl;
		std::cout << buffer<<std::endl;
	}
	delete buffer;
}

int main(int argc, char *argv[])
{
	std::cout << "**********************文件字符串测试开始!**********************" << std::endl;
	std::string fileStr = "E:\\jing_zhong\\ConsoleApplication1\\ConsoleApplication1\\main.cpp";
	//fileStr = "C:/Users/Lenovo/source/repos/ConsoleApplication1/x64/Release/test.docx";
	Test_fileStr(fileStr);
	std::cout << "**********************文件字符串测试结束!**********************" << std::endl;

	std::cout << "**********************文件夹和文件读写测试开始!**********************" << std::endl;
	Test_fileFolder();
	std::cout << "**********************文件夹和文件读写测试结束!**********************" << std::endl;
	return 0;
}

运行结果如下:
C++ 自己动手实现简单的文件操作 (2023.6.23)_第58张图片

4、总结

        文件的本质应该是基于软件高级编程语言中的数据类型,由很多阿拉伯数字、字符组成的有规律、可构造和可解析的体块存储于文本文件或二进制文件中,在操作系统中基于不同的扩展名与相应的软件应用进行文件关联,让用户无需疲于寻找打开特定扩展名文件的软件,但有能力的开发者一定是需要透过现象看本质,知其然更能知其所以然,以便从容应对未知挑战、以不变应万变,方可坚定自信,对真理自主可控,对现象了然于胸,以立于不败之地

        正所谓数据(Data)软件(Software)标准(Standard)生态(Ecology)应用(Application)这五大方面相辅相成、不可或缺、缺一不可,本人才疏学浅,暂将上述这五个方面以英文首字母概括为DSSEA,希望能在这里与广大开发者共勉!!!

C++ 自己动手实现简单的文件操作 (2023.6.23)_第59张图片 C++ 自己动手实现简单的文件操作 (2023.6.23)_第60张图片
我在朦胧中,眼前展开一片海边碧绿的沙地来,上面深蓝的天空中挂着一轮金黄的圆月。我想:希望是本无所谓有,无所谓无的。这正如地上的路;其实地上本没有路,走的人多了,也便成了路。

——节选自`鲁迅`先生的《故乡》

        路虽远,行则将至;事虽难,做则必成。恰巧毕业一年,内心深有感触,当然也在不断接受生活、工作和学习的考验,自己仍在思索求学二十载如何能够学有所成,在浩浩荡荡、滚滚不断的历史长河中实现自己的人生价值,提高自己的人生追求,为国为民,奉献青春。最后,正逢端午佳节之际,在思念家人和友人的同时,也时常告诫自己要不忘初心,开阔视野和心胸,耐得住寂寞,与自己和解,坚持真理,静候佳人,回馈父母,时光不负赶路人,美好年华,时不我待 ,作者在此给各位粉丝、广大的劳动者、奋战在一线的高危行业工作者及全国人民送上真诚的问候,世上有大爱,人间有真情,愿大家端午快乐,吃大大的粽子,用满满的情意对待身边的人和事

你可能感兴趣的:(C++,实践经验,c++,文件操作)