文件操作用得比较少,按楼主的意思写了个windows平台下的
注意:不保证安全性,使用前请首先确认是否符合要求。操作前请备份原文件。本人对造成的损失概不负责!#include <iostream>
#include <vector>
#include <string>
#include <io.h>
#include <windows.h>
using namespace std;
//连接路径
string linkpath(string path, string path2="",string path3="") {
if (path2 != "") {
if (path.back() != '\\')
path.push_back('\\');
path += path2;
}
if (path3 != "") {
if (path.back() != '\\')
path.push_back('\\');
path += path3;
}
return path;
}
//寻找路径中的所有文件和文件夹
pair<vector<string>,vector<string>> findAllFiles(string path) {
intptr_t handle;
_finddata_t findinfo;
pair<vector<string>, vector<string>> ret;
path = linkpath(path, "*");
handle = _findfirst(path.c_str(), &findinfo);
if (handle == -1) return ret;
do {
string tmp = findinfo.name;
if (tmp == "." || tmp == "..") continue;
if (findinfo.attrib == _A_SUBDIR) {
ret.second.push_back(tmp);
}
else {
ret.first.push_back(tmp);
}
} while (!_findnext(handle, &findinfo));
_findclose(handle);
return ret;
}
//分割扩展名和文件名
pair<string, string> splitfname(string name) {
auto tmp = find(name.rbegin(), name.rend(), '.');
if (tmp == name.rend()) return { name,"" };
auto tmp2 = tmp.base();
return { string(name.begin(),tmp2-1),string(tmp2,name.end())};
}
//获取前缀
string prefix(string name,char seprator='_') {
name = splitfname(name).first;
auto tmp = find(name.begin(), name.end(), seprator);
if (tmp == name.end()) return "";
return name.substr(0, tmp - name.begin());
}
//主函数
void CollateFiles(string path){
auto ret = findAllFiles(path);
auto& files = ret.first;
auto& dirs = ret.second;
int n = 0;
int m = 0;
for (string s : files) {
string p = prefix(s);
if (find(dirs.begin(), dirs.end(), p) == dirs.end()) {
CreateDirectory(linkpath(path, p).c_str(), nullptr);
++m;
dirs.push_back(p);
}
MoveFile(linkpath(path, s).c_str(), linkpath(path, p, s).c_str());
++n;
}
cout << "整理完毕,共创建" << m << "个文件夹,移动" << n << "个文件" << endl;
}
int main() {
CollateFiles("D:\\b\");
system("pause");
}
|