C++17 filesystem使用

问题

a目录下有多个话单文件,话单记录以“,”分割,需要统计每个文件的字段有值的数量,无值的数量,输出日志文件;统计完的文件移动到备份目录。

1 遍历文件目录

2 操作每个文件:
  统计有值字段、无值字段、
  输出日志
  将文件移动到备份目录

代码只能在windows下通过:

#include <filesystem>
#include <iostream>
#include <regex>  //正则表达式
#include <string>
#include <fstream>

using namespace std;
namespace fs = std::experimental::filesystem;

namespace
{
	fs::path src_path = fs::path("..") / "srcdir";	//	源目录
	fs::path bk_path = fs::path("..") / "bkdir";	//	备份目录
	regex fileSuffix("(.*)(.txt)");					//	话单文件 *.txt  
	string log_file = "../log.txt";					//	日志
	const char delemiter = ',';						//	分隔符
}


//	统计话单文件中的字段
static bool fileOperate(const fs::path &myfile)
{
	ifstream read(myfile.string(), std::ios::binary | std::ios::_Nocreate | std::ios::out);
	ofstream write(log_file, std::ios::app);
	try {
		if (!read.is_open() || !write.is_open())
		{
			throw std::invalid_argument("error: file open failed!");
		}
	}
	catch (const std::invalid_argument& e)
	{
		cout << e.what() << endl;
		return false;	//	程序出错
	}

	unsigned valid_keys = 0;	//	有效字段计数
	unsigned empty_keys = 0;	//	空字段计数

	string buffer;
	read >> buffer;

	cout << myfile.filename() << " length is: " << buffer.length() << endl;
	cout << buffer << "\n\n";

	int last_pos = -1;		//	记录上次位置
	size_t cur_pos = 0;		//	记录当前位置

	for (size_t i = 0; i < buffer.length(); ++i)
	{
		if (buffer.at(i) == delemiter)
		{
			cur_pos = i;

			if (cur_pos > last_pos + 1)
				++valid_keys;
			else
				++empty_keys;

			last_pos = cur_pos;
		}
	}

	write << myfile.filename() << " valid keys: " << valid_keys
		  << "\t" << " empty keys: " << empty_keys << "\n\n";

	read.close();
	write.close();
	return true;
}

int main()
{
	std::cout << "Current path is " << fs::current_path() << endl
		<< "srcdir is " << canonical(src_path) << endl
		<< "bkdir is " << canonical(bk_path) << "\n\n";


	//	遍历源目录下所有话单文件
	for (auto &DirectoryIter : fs::directory_iterator(src_path))
	{
		auto filepath = DirectoryIter.path();
		auto filename = filepath.filename();

		//	判断是否是话单文件
		if (std::regex_match(filename.string(), fileSuffix))
		{
			auto src_file = src_path / filename;	//	话单文件
			auto bk_file = bk_path / filename;		//	备份文件

			//	统计话单文件中的字段
			bool success = fileOperate(src_file);
			if (!success)
			{
				cout << " file statistic fialed!" << endl;
				exit(EXIT_FAILURE);
			}

			//	话单文件备份
			fs::copy(src_file, bk_file, fs::copy_options::update_existing);	//	update_existing:如果已有则更新备份话单文件
		}

	}

	getchar();

	return EXIT_SUCCESS;
}

换成Centos7后,代码如下:

#include <iostream>
#include <dirent.h>
#include <string>
#include <regex> 
#include <fstream>

using namespace std;

namespace
{
	const string src_path = "./srcdir";				//	源目录
	const string bk_path  = "./bkdir";				//	备份目录
	const string log_file = "./log.txt";			//	日志
	const char delemiter = ',';						//	分隔符
	regex fileSuffix("(.*)(.txt)");					//	话单文件 *.txt  
}

//	统计话单文件中的字段
static bool fileStatistic(const string &myfile)
{

	ifstream read(myfile, std::ios::in);
	ofstream write(log_file, std::ios::out | std::ios::app);

	if (!read.is_open() || !write.is_open())
	{
		cout << "file open error!" << endl;
		return false;	//	文件打开失败
	}

	unsigned valid_keys = 0;	//	有效字段计数
	unsigned empty_keys = 0;	//	空字段计数

	string buffer;
	read >> buffer;

	cout << myfile << " length is: " << buffer.length() << endl;
	cout << buffer << "\n\n";

	int last_pos = -1;		//	记录上次位置
	size_t cur_pos = 0;		//	记录当前位置

	for (size_t i = 0; i < buffer.length(); ++i)
	{
		if (buffer.at(i) == delemiter)
		{
			cur_pos = i;

			if (cur_pos > last_pos + 1)
				++valid_keys;
			else
				++empty_keys;

			last_pos = cur_pos;
		}
	}

	write << myfile << " valid keys: " << valid_keys
		  << "\t" << " empty keys: " << empty_keys << "\n\n";
	
	cout << myfile << " valid keys: " << valid_keys
	  << "\t" << " empty keys: " << empty_keys << "\n\n";

	read.close();
	write.close();
	
	return true;
}

//	话单文件备份
static bool fileBackup(const string &myfile)
{
	ifstream read(src_path + "/" + myfile, std::ios::in);
	ofstream write(bk_path + "/" + myfile, std::ios::out);

	if (!read.is_open() || !write.is_open())
	{
		cout << "file open error!" << endl;
		return false;	//	文件打开失败
	}
	
	string buffer;
	read >> buffer;
	write << buffer;
	
	read.close();
	write.close();
	
	return true;
}

int main(int argc,char *argv[])
{
    DIR * dp;
    struct dirent *filename;

    dp = opendir(src_path.c_str());
    if (!dp)
    {
        fprintf(stderr,"open directory error\n");
        return EXIT_FAILURE;
    }
	
	//	遍历源目录下所有话单文件
    while (filename = readdir(dp))
    {
		if (std::regex_match(filename->d_name, fileSuffix))
		{
			
			//	统计话单文件中的字段
			bool success = fileStatistic(src_path + "/" + filename->d_name);
			if (!success)
			{
				fprintf(stderr,"file statistic fialed!\n");
				exit(EXIT_FAILURE);
			}
			
			//	话单文件备份
			success = fileBackup(filename->d_name);
			if (!success)
			{
				fprintf(stderr,"file backup fialed!\n");
				exit(EXIT_FAILURE);
			}
		}
    }
	
    closedir(dp);
    return EXIT_SUCCESS;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值