C++文件系统的学习,学习要义,所有的学习例程都需要自己动手去实现,才能掌握真谛。
本片文章将C++文件系统必须要掌握的四种类型的常见用法都写出来了,你可以在自己的电脑上,copy验证效果。
若只是想要文件清空病毒的代码,直接看文章末尾
学习准备:若用的是visual studio 需要将点击项目属性,把C++标准设置到c++17标准或以上
首先要知道filesystem主要用来处理文件目录,也就是文件夹创建和删除,遍历,不是用来读写文件
需要掌握的四个类:
1.path类:
路径处理
2.file_status类
通过filesystem::status()可以构建相应对象
filesystem::file_status object;
object.type(); 查看文件类型
3.directory_entry类
文件路口
directory_entry object;
object.statue().type();
此类不可以object.path().filename().string();
4.directory_iterator类
directory_iterator begin(path对象),end;
两种遍历文件方法
1.
for(auto v:begin){
cout<<v<<endl;
}
2.
set<string> dirset;
filesystem::path dir("文件路径");
for (filesystem::directory_iterator end, begin(dir); begin != end; ++begin) {
if (!filesystem::is_directory(begin->path())) {
dirset.insert(begin->path().filename().string());
}
}
总结重点:需要掌握这四个类中,各自可以调用哪些函数,比如path(),filename(),string(),statue(),type();
1:可以通过statue( path类型对象,如"test" )函数构建一个file_statue类型的对象,
该对象可以调用type()函数, 如 对象.type() 得到对象的文件类型
以此和filesystem::file_type中的类型比较该对象属于哪种文件类型(文件,还是文件夹).
如filesystem::file_type::directory(文件夹)
filesystem::file_type::regular (普通文件)
2:filesystem::directory_entry类型的对象,可以调用的函数,如: 对象.statue().type() 这样就跟上边一样的效果了
3:filesystem::directory_iterator类型的对象,如: 对象.path().filename().string()
细节:path()和filename()得到的结果 都有 引号,path()得到的是具体文件对象距离当前文件夹的相对路径,
filename()得到的是具体文件名,而再通过string()函数实现去掉引号。
4:directory_entry和directory_iterator有一个小细节,前者对象指向的是当前文件夹。
后者因为是迭代器对象,默认指在当前文件夹下的第一个文件上。并且类型是directory_entry。
5:文件系统中的string()作用就是拿来去除掉引号,并且将\\ 变成 \。
文件目录的遍历
#include<filesystem>
#include<iostream>
using namespace std;
int main() {
filesystem::path url("fileBox");
if (!filesystem::exists(url)) {
cout << "不存在!\n";
}
else {
cout << "存在!\n";
}
filesystem::create_directory("fileBox");
filesystem::create_directory("fileBox/file1");错误,此函数不能多层创建目录
filesystem::create_directories("a/b/c");//这个就可以
使用error_code结构来寻找错误
error_code temp;
filesystem::create_directories("\fileBox",temp);
cout << temp.message() << endl;
filesystem::path removeUrl("a");
filesystem::remove_all(removeUrl);//删除
获取最后修改时间
auto time = filesystem::last_write_time("fileBox");
return 0;
}
1.path类的常见使用
#include<filesystem>
#include<iostream>
using namespace std;
int main() {
构造一个path路径
filesystem::path url("boxFile");
当前程序路径
filesystem::path curURL = filesystem::current_path();
cout << "当前路径" << curURL << endl; //两根斜杠
cout << "当前路径:" << curURL.string() << endl; //一根斜杠
cout << "根目录: " << curURL.root_directory() << endl;
cout << "对于根目录的相对路径:" << curURL.relative_path() << endl;
cout << "根名:" << curURL.root_name() << endl;
cout << "根路径:" << curURL.root_path() << endl;
return 0;
}
2.file_status类的常见使用
#include<filesystem>
#include<iostream>
#include<fstream>
using namespace std;
void demo_status(filesystem::file_status object) {
switch (object.type())
{
case filesystem::file_type::regular:
cout << "常规磁盘文件!\n";
break;
case filesystem::file_type::directory:
cout << "目录文件!\n";
break;
case filesystem::file_type::not_found:
cout << "目录不存在!\n";
break;
case filesystem::file_type::unknown:
cout << "无法识别文件!\n";
break;
default:
break;
}
}
int main() {
filesystem::create_directories("fileBox");
demo_status(filesystem::status("fileBox"));
fstream file("fileBox\\file", ios::out | ios::trunc);
if (!file.is_open()) {
cout << "文件创建失败!\n";
}
demo_status(filesystem::status("fileBox\\file"));//status的返回值就是file_status类型
return 0;
}
3.directory_entry类和directory_iterator的常见使用
#include<filesystem>
#include<iostream>
#include<set>
using namespace std;
/*
directory_entry: 入口
directory_iterator: 遍历文件
*/
遍历当前目录下所有文件夹
void traverseDirectory() {
filesystem::path URL("C:\\Users\\ASUS\\Desktop\\第22课 C++文件系统");
自己写代码,一定要判断是否存在
if (!filesystem::exists(URL)) {
cout << "当前目录不存在" << endl;
}
filesystem::directory_entry input(URL);
if (input.status().type() == filesystem::file_type::directory) {
cout << "该path是一个目录!\n";
}
遍历同级目录中的所有文件和文件夹
只需要通过path构造一个directory_iterator 对象即可
filesystem::directory_iterator list(URL);
for (auto v : list) {
先调用path获取path对象,再调用filename得到文件夹的名字
cout << v << endl;
}
}
遍历当前文件夹中的所有文件(只是文件,不包括文件夹)
void traverseDirectoryAllFile() {
filesystem::path dir("C:\\Users\\ASUS\\Desktop");
set<string> dirset;
for (filesystem::directory_iterator end, begin(dir); begin != end; ++begin) {
if (!filesystem::is_directory(begin->path())) {
dirset.insert(begin->path().filename().string());
}
}
for (auto v : dirset) {
cout << v << endl;
}
}
遍历当前文件夹中所有目录文件 ,跟上一种比只需要换一种类,其他操作都一样(recursive_directory_iterator)
void traverseAllDirectoryFile() {
filesystem::path dir("C:\\Users\\ASUS\\Desktop");
set<string> dirset;
for (filesystem::recursive_directory_iterator end, begin(dir); begin != end; ++begin) {
if (!filesystem::is_directory(begin->path())) {
dirset.insert(begin->path().filename().string());
}
}
for (auto v : dirset) {
cout << v << endl;
}
}
删除当前路径下的所有文件
void deleteURLAllFile() {
filesystem::path root = filesystem::current_path();
filesystem::remove_all(root / "Debug");
方法一:
filesystem::remove_all(root); 不可行,因为当前程序在运行,无法删除
方法二:
set<string> dirset;
for (filesystem::directory_iterator end, begin(root); begin != end; ++begin) {
if (!filesystem::is_directory(begin->path())) {
dirset.insert(begin->path().filename().string());
}
}
for (auto v : dirset) {
cout << v << endl;
if (v != "文件系统.exe")
filesystem::remove(root / v);
}
}
int main() {
traverseDirectory();
traverseDirectoryAllFile();
return 0;
}
总结使用
#include<filesystem>
#include<iostream>
using namespace std;
void testPath() {
filesystem::path url("1.txt");
if (filesystem::exists(url)) {
cout << "存在!\n";
}
else {
cout << "不存在!\n";
}
filesystem::create_directories("a/b/cc");
filesystem::remove_all("a/b/cc");
}
void testDirectory() {
filesystem::directory_entry entry(filesystem::path("fileBox"));
if (entry.status().type() == filesystem::file_type::directory) {
cout << "是一个文件!\n";
cout << entry<<endl;
}
filesystem::directory_iterator begin("fileBox");
cout << begin->path()<<endl;
cout << begin->path().filename() << endl;
cout << begin->path().string() << endl;
cout << begin->path().filename().string() << endl;
for (auto v:begin) { //auto = filesystem::directory_entry
cout << v << endl;
}
filesystem::is_directory(begin->path().string());
filesystem::is_directory(begin->path().filename().string());
}
int main() {
testPath();
testDirectory();
return 0;
}
总结使用2:
文件清空利器
//具体使用方法,只编译生成对应的exe.文件即可,直接在编译器里运行会报错,如果你仔细学习了以上内容,就会明白为何报错。
直接将生成的对应exe.文件放到你想要清空的文件目录下, 双击exe.文件即可删除所有文件。
#include<filesystem>
#include <iostream>
#include<set>
using namespace std;
int main()
{
filesystem::path curPath = filesystem::current_path().string();
set<string>tmp;
filesystem::directory_iterator begin(curPath), end;
for (; begin != end; begin++) {
if (begin->path().filename().string() != "文件病毒.exe") {
cout << begin->path().filename().string() << endl;
tmp.insert(begin->path().filename().string());
}
}
for (auto v : tmp) {
filesystem::remove_all(curPath / v);
}
return 0;
}