优化代码第一天的代码

优化交互体验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// first programme with c++ 
#include <iostream>
#include <string>
#include <filesystem>

namespace fs = std::filesystem;

void inputCheck(std::string dirPath, std::string newPrefix, std::string needSuffix) {
if (dirPath.empty() newPrefix.empty() needSuffix.empty()) {
std::cerr << "Error: " << "directory_path new_prefix need_rename_suffix cannot be empty" << std::endl;
std::cout << "Please input again" << std::endl;
}
}

void dirCheck(fs::path dirPath) {
if (!fs::exists(dirPath) !fs::is_directory(dirPath)) {
std::cerr << "Error: path not exist or not a directory" << std::endl;
exit(1);
}
}

void renamefile(fs::path dirPath, std::string newPrefix, std::string needSuffix) {
int count = 0;
try {
for (const auto& entry : fs::directory_iterator(dirPath)) {
if (entry.is_regular_file() && entry.path().extension().string() == needSuffix) {
fs::path oldPath = entry.path();
fs::path newPath = oldPath.parent_path() / (newPrefix + std::to_string(count+1) + oldPath.extension().string());
fs::rename(oldPath, newPath);
std::cout << "Renamed: " << oldPath.filename().string() << " -> " << newPath.filename().string() << std::endl;
count++;
}
}
} catch(const std::filesystem::filesystem_error& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
std::cout << "Total files renamed: " << count << std::endl;
}

int main() {
std::cout << "Input the directory path, new prefix, need rename suffix" << std::endl;
std::string inputPath, newPrefix, needSuffix;
do {
std::cin >> inputPath >> newPrefix >> needSuffix;
inputCheck(inputPath, newPrefix, needSuffix);
}while(inputPath.empty() newPrefix.empty() || needSuffix.empty());
fs::path dirPath(inputPath);
dirCheck(dirPath);
renamefile(dirPath, newPrefix, needSuffix);

return 0;
}

今天的代码——文件监控器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <windows.h>
#include <iostream>
#include <string>
#include <filesystem>
#include <fcntl.h>
#include <io.h>
#include <cstdio>
#include <csignal>

// 全局变量用于控制程序退出
volatile bool running = true;

// 信号处理函数
void signalHandler(int signum) {
if (signum == SIGINT) {
running = false;
}
}

void DisplayFileAction(DWORD dwAction)
{
switch (dwAction)
{
case FILE_ACTION_ADDED:
std::wcout << L"File Created" << std::endl;
break;
case FILE_ACTION_REMOVED:
std::wcout << L"File Deleted" << std::endl;
break;
case FILE_ACTION_MODIFIED:
std::wcout << L"File Modified" << std::endl;
break;
case FILE_ACTION_RENAMED_OLD_NAME:
std::wcout << L"File Renamed (Old Name)" << std::endl;
break;
case FILE_ACTION_RENAMED_NEW_NAME:
std::wcout << L"File Renamed (New Name)" << std::endl;
break;
default:
std::wcout << L"Unknown Action" << std::endl;
break;
}
}

int main()
{
// 设置信号处理
signal(SIGINT, signalHandler);

// Set console output to UTF-16
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_U16TEXT);

// input directory you want to monitor
std::wstring directory;
std::wcout << L"Enter the directory you want to monitor: ";
std::getline(std::wcin, directory);

// 创建监控句柄,handle(句柄)是一个用于标识和访问系统资源(例如文件或目录)的引用
HANDLE hDir = CreateFileW(
directory.c_str(), // 被监控目录的路径
FILE_LIST_DIRECTORY, // 监控的目录操作权限
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 共享模式,允许其他进程对目录进行读、写、删除操作
NULL, // 默认的安全属性
OPEN_EXISTING, // 打开已存在的目录
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, // 文件标志,支持备份语义及异步操作
NULL // 无模板文件
);

if (hDir == INVALID_HANDLE_VALUE)//打开失败
{
std::wcerr << L"Error: Cannot open directory " << directory << std::endl;
return 1;
}

std::wcout << L"Monitoring directory: " << directory << std::endl;
std::wcout << L"Press Ctrl+C to exit" << std::endl;

// Allocate buffer
const DWORD BUFFER_SIZE = 4096; //缓冲区大小
BYTE buffer[BUFFER_SIZE] = { 0 }; //缓冲区
DWORD bytesReturned; //返回字节数
OVERLAPPED overlapped = { 0 }; //重叠结构
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //创建事件

while (running)
{
// Start async monitoring
BOOL success = ReadDirectoryChangesW( //读取目录变化
hDir,//目录句柄
buffer,//缓冲区
BUFFER_SIZE,//缓冲区大小
TRUE,//监控子目录
FILE_NOTIFY_CHANGE_FILE_NAME | //文件名
FILE_NOTIFY_CHANGE_DIR_NAME | //目录名
FILE_NOTIFY_CHANGE_ATTRIBUTES | //属性
FILE_NOTIFY_CHANGE_SIZE | //大小
FILE_NOTIFY_CHANGE_LAST_WRITE | //最后写入
FILE_NOTIFY_CHANGE_LAST_ACCESS | //最后访问
FILE_NOTIFY_CHANGE_CREATION | //创建
FILE_NOTIFY_CHANGE_SECURITY, //安全
&bytesReturned, //返回字节数
&overlapped, //重叠结构
NULL //模板文件
);

if (!success)
{
std::wcerr << L"ReadDirectoryChangesW failed" << std::endl;
break;
}

// 设置较短的超时时间,以便能够检查 running 标志
DWORD waitResult = WaitForSingleObject(overlapped.hEvent, 1000);

if (waitResult == WAIT_OBJECT_0)
{
FILE_NOTIFY_INFORMATION* pNotify = (FILE_NOTIFY_INFORMATION*)buffer; //文件通知信息

do
{
// Get filename
std::wstring filename(pNotify->FileName, pNotify->FileNameLength / sizeof(WCHAR)); //文件名

// Display action type and filename
std::wcout << L"File: " << filename << L" - ";
DisplayFileAction(pNotify->Action); //显示文件操作
// Move to next record
if (pNotify->NextEntryOffset == 0) //没有下一个记录
break;
pNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pNotify + pNotify->NextEntryOffset); //移动到下一个记录
} while (true);

// Reset event
ResetEvent(overlapped.hEvent); //重置事件
}
}

std::wcout << L"\nExiting program..." << std::endl;

// Cleanup
CloseHandle(overlapped.hEvent); //关闭事件
CloseHandle(hDir); //关闭目录

return 0;
}