问题
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;
}