Skip to content

Instantly share code, notes, and snippets.

@qycyfjy
Created October 13, 2023 11:27
Show Gist options
  • Save qycyfjy/d2e8aa8245ebb46f3396e4fc69f85a4e to your computer and use it in GitHub Desktop.
Save qycyfjy/d2e8aa8245ebb46f3396e4fc69f85a4e to your computer and use it in GitHub Desktop.
MSVC下使用<filesystem>
主旨就是:
1.源文件使用UTF-8编码
2.编译选项加上/utf-8
3.涉及到路径的操作统统使用w系列字符串: 使用wstring而不是string, 使用wstringstream而不是stringstream等等, 在使用字符串字面量时使用L""前缀, 类型为const wchar_t*
4.可以在构造一个path后使用make_preferred()把间隔符统一了, 防止'/', '\\'混杂不和谐
注意第三条, 是涉及路径, 不是涉及文件, 一个典型的顺序是:
1. 使用wstring类型的文件路径(如果来源不是wstring/wchar_t要分情况把ANSI(一般是从控制台获得的输入)或者UTF-8转为wstring的UTF-16)构造一个path
2. 使用这个path构造一个fstream
3. 按文件内容是binary还是各种编码的文本去处理, 很多时候文本文件都是UTF-8编码所以按char进行读写, binary也要按char读写, 之后就是一水的char[]/string了
// ReSharper disable CppClangTidyClangDiagnosticInvalidSourceEncoding
// ReSharper disable StringLiteralTypo
#include <Windows.h> // WideCharToMultiByte用于把宽字符UTF-16转为UTF-8 SetConsoleOutputCP控制控制台输出代码页为UTF-8
#undef min
#undef max
#include <iostream>
#include <iomanip>
#include <sstream>
#include <filesystem>
#include <fstream>
using namespace std;
using namespace std::filesystem;
string wide2_utf8(const wstring_view& wstr)
{
const int count = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.length()), nullptr, 0, nullptr, nullptr);
std::string str(count, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), -1, str.data(), count, nullptr, nullptr);
return str;
}
wstring file_detail(const path& path_of_file)
{
wostringstream wos;
int i = 0;
wos << L"\t当前文件组成: " << path_of_file << endl;
for (auto iter = path_of_file.begin(); iter != path_of_file.end(); ++iter)
{
wos << L"\t\t第" << i++ << L"部分: " << *iter << endl;
}
wos << L"\t根目录名 = " << path_of_file.root_name() << endl
<< L"\t根目录路径 = " << path_of_file.root_path() << endl
<< L"\t相对路径 = " << path_of_file.relative_path() << endl
<< L"\t父路径 = " << path_of_file.parent_path() << endl
<< L"\t文件名 = " << path_of_file.filename() << endl
<< L"\t无扩展名 = " << path_of_file.stem() << endl
<< L"\t拓展名 = " << path_of_file.extension() << endl;
return wos.str();
}
int main()
{
::SetConsoleOutputCP(65001);
path sample_file(L"D:/WeGameApps/地下城与勇士:创新世纪/地下城与勇士:创新世纪");
sample_file.make_preferred();
const path summary_path = sample_file.parent_path() / L"总结.txt";
if(exists(summary_path))
{
remove(summary_path);
}
auto directory_iter = directory_iterator(sample_file.parent_path());
int file_count = 0;
int dir_count = 0;
bool detail = false;
wostringstream wos;
for (; directory_iter != directory_iterator(); ++directory_iter)
{
if (directory_iter->is_regular_file())
{
++file_count;
wos << L"<R>";
detail = true;
}
else
{
++dir_count;
wos << L"<D>";
detail = false;
}
wos << directory_iter->path() << endl;
if (detail)
{
wos << file_detail(directory_iter->path());
}
}
stringstream out;
out << "一共" << file_count << "个普通文件, " << dir_count << "个文件夹" << endl;
out << wide2_utf8(wos.str()) << endl;
if (ofstream summary(summary_path, ios_base::trunc); summary.is_open())
{
summary << out.rdbuf();
cout << "完成, 请查看" << wide2_utf8(summary_path.c_str()) << endl;
}
else
{
cout << "无法创建文件, 打印到控制台" << endl;
cout << out.rdbuf();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment