11#include " File_System.h"
22
3- shared_ptr<Disk> diskData;
4- shared_ptr<Directory> currentDirectory;
5- shared_ptr<User> currentUser;
6- const string SAVE_PATH = " disk.dat" ;
3+ shared_ptr<Disk> diskData;// 磁盘数据
4+ shared_ptr<Directory> currentDirectory;// 当前目录
5+ shared_ptr<User> currentUser;// 当前用户
6+ const string SAVE_PATH = " disk.dat" ;// 保存磁盘数据的文件路径
77shared_ptr<FileControlBlock> copiedFile = nullptr ;// 初始化全局变量来保存拷贝的文件信息
88set<string> openFiles; // 初始化已打开文件的集合
99string openFileName = " " ; // 初始化当前打开的文件名
10- mutex diskMutex;
11- condition_variable cv;
12- bool exitFlag = false ;
13- queue<string> commandQueue;
10+ mutex diskMutex;// 初始化磁盘数据的互斥锁
11+ condition_variable cv;// 初始化条件变量
12+ bool exitFlag = false ;// 初始化推出变量
13+ queue<string> commandQueue;// 初始化命令队列
1414
1515// 打印帮助信息
1616void printHelp () {
@@ -45,87 +45,104 @@ void printHelp() {
4545
4646// 解析用户输入的命令
4747vector<string> inputResolve (const string& input) {
48- vector<string> result;
49- istringstream iss (input);
50- string token;
48+ vector<string> result; // 用于存储解析后的单词
49+ istringstream iss (input);// 使用 istringstream 将字符串转换为输入流
50+ string token; // 用于存储从输入流中提取的每个单词
5151 while (iss >> token) {
52- result.push_back (token);
52+ result.push_back (token);// 将提取的单词加入结果向量
5353 }
5454 return result;
5555}
5656
5757// 递归保存目录和文件
5858void saveDirectory (ofstream& file, shared_ptr<Directory> directory) {
59+ // 获取当前目录的子目录数量和文件数量
5960 size_t dirCount = directory->children .size ();
6061 size_t fileCount = directory->files .size ();
62+
63+ // 将子目录数量写入文件
6164 file.write (reinterpret_cast <const char *>(&dirCount), sizeof (dirCount));
65+
66+ // 遍历每个子目录
6267 for (const auto & dir : directory->children ) {
68+ // 获取子目录名称长度并写入文件
6369 size_t dirNameLen = dir->fileControlBlock ->fileName .size ();
6470 file.write (reinterpret_cast <const char *>(&dirNameLen), sizeof (dirNameLen));
71+ // 写入子目录名称
6572 file.write (dir->fileControlBlock ->fileName .c_str (), dirNameLen);
66- saveDirectory (file, dir); // 递归保存子目录
73+ // 递归保存子目录
74+ saveDirectory (file, dir);
6775 }
76+ // 将文件数量写入文件
6877 file.write (reinterpret_cast <const char *>(&fileCount), sizeof (fileCount));
78+
79+ // 遍历每个文件
6980 for (const auto & fcb : directory->files ) {
81+ // 获取文件名称长度并写入文件
7082 size_t fileNameLen = fcb->fileName .size ();
71- size_t contentLen = fcb->content .size ();
7283 file.write (reinterpret_cast <const char *>(&fileNameLen), sizeof (fileNameLen));
84+ // 写入文件名称
7385 file.write (fcb->fileName .c_str (), fileNameLen);
86+ // 获取文件内容长度并写入文件
87+ size_t contentLen = fcb->content .size ();
7488 file.write (reinterpret_cast <const char *>(&contentLen), sizeof (contentLen));
89+ // 写入文件内容
7590 file.write (fcb->content .c_str (), contentLen);
91+ // 写入文件读写指针位置
7692 file.write (reinterpret_cast <const char *>(&fcb->readWritePointer ), sizeof (fcb->readWritePointer ));
93+ // 写入文件锁定状态
7794 file.write (reinterpret_cast <const char *>(&fcb->isLocked ), sizeof (fcb->isLocked ));
7895 }
7996}
8097
8198// 递归加载目录和文件,并设置父目录指针
8299void loadDirectory (ifstream& file, shared_ptr<Directory> directory) {
83- size_t dirCount, fileCount;
84- file.read (reinterpret_cast <char *>(&dirCount), sizeof (dirCount));
85-
100+ size_t dirCount, fileCount;// 子目录数量和文件数量
101+ file.read (reinterpret_cast <char *>(&dirCount), sizeof (dirCount));// 读取当前目录的子目录数量
102+ // 遍历每个子目录
86103 for (size_t i = 0 ; i < dirCount; ++i) {
87104 string dirName;
88105 size_t dirNameLen;
89- file.read (reinterpret_cast <char *>(&dirNameLen), sizeof (dirNameLen));
106+ file.read (reinterpret_cast <char *>(&dirNameLen), sizeof (dirNameLen));// 读取子目录名称长度
90107 dirName.resize (dirNameLen);
91108 file.read (&dirName[0 ], dirNameLen);
92-
109+ // 创建子目录并设置其属性
93110 auto dir = make_shared<Directory>();
94111 dir->fileControlBlock = make_shared<FileControlBlock>();
95112 dir->fileControlBlock ->fileName = dirName;
96113 dir->fileControlBlock ->isDirectory = true ;
97114 dir->parentDirectory = directory; // 设置父目录指针
98-
115+ // 将子目录加入当前目录的子目录列表
99116 directory->children .push_back (dir);
100-
101117 loadDirectory (file, dir); // 递归加载子目录
102118 }
103-
119+ // 读取当前目录的文件数量
104120 file.read (reinterpret_cast <char *>(&fileCount), sizeof (fileCount));
105- for (size_t i = 0 ; i < fileCount; ++i) {
121+ for (size_t i = 0 ; i < fileCount; ++i) {// 遍历每个文件
106122 string fileName, content;
107123 size_t fileNameLen, contentLen;
108-
124+ // 读取文件名称长度
109125 file.read (reinterpret_cast <char *>(&fileNameLen), sizeof (fileNameLen));
110126 fileName.resize (fileNameLen);
111127 file.read (&fileName[0 ], fileNameLen);
112-
128+ // 读取文件内容长度
113129 file.read (reinterpret_cast <char *>(&contentLen), sizeof (contentLen));
114130 content.resize (contentLen);
115131 file.read (&content[0 ], contentLen);
116-
132+ // 创建文件控制块并设置其属性
117133 auto fcb = make_shared<FileControlBlock>();
118134 fcb->fileName = fileName;
119135 fcb->isDirectory = false ;
120136 fcb->content = content;
121137
122138 file.read (reinterpret_cast <char *>(&fcb->readWritePointer ), sizeof (fcb->readWritePointer ));
123139 file.read (reinterpret_cast <char *>(&fcb->isLocked ), sizeof (fcb->isLocked ));
124-
140+ // 将文件控制块加入当前目录的文件列表
125141 directory->files .push_back (fcb);
126142 }
127143}
128144
145+ // 保存磁盘数据到文件
129146bool saveDisk (const string& path) {
130147 ofstream file (path, ios::binary);
131148 if (!file.is_open ()) {
@@ -149,7 +166,7 @@ bool saveDisk(const string& path) {
149166 return true ;
150167}
151168
152-
169+ // 加载磁盘数据
153170bool loadDisk (const string& path) {
154171 ifstream file (path, ios::binary);
155172 if (!file.is_open ()) {
@@ -275,17 +292,14 @@ void reloadDisk(const string& path) {
275292
276293// 获取当前时间字符串
277294string getCurrentTime () {
278- time_t now = time (0 );
295+ time_t now = time (0 );// 获取当前时间点
279296 tm localtm;
280297 localtime_s (&localtm, &now);
281298 char buffer[80 ];
282299 strftime (buffer, sizeof (buffer), " %Y-%m-%d %H:%M:%S" , &localtm);
283300 return string (buffer);
284301}
285302
286-
287-
288-
289303// 初始化磁盘
290304void initDisk () {
291305 diskData = make_shared<Disk>();
@@ -363,7 +377,7 @@ void makeDirectory(const string& dirname) {
363377 dir->fileControlBlock = make_shared<FileControlBlock>();
364378 dir->fileControlBlock ->fileName = dirname;
365379 dir->fileControlBlock ->isDirectory = true ;
366- dir->parentDirectory = currentDirectory; // 设置父目录指针
380+ dir->parentDirectory = currentDirectory; // 设置父目录指针。 将新目录添加到当前目录的子目录列表中
367381 currentDirectory->children .push_back (dir);
368382 cout << " 目录创建成功。" << endl;
369383 saveDisk (SAVE_PATH);
@@ -389,7 +403,7 @@ void changeDirectory(const string& dirname) {
389403 cout << " 无效的目录名。" << endl;
390404 return ;
391405 }
392- for (const auto & dir : currentDirectory->children ) {
406+ for (const auto & dir : currentDirectory->children ) {// 遍历当前目录的子目录
393407 if (dir->fileControlBlock ->fileName == dirname) {
394408 currentDirectory = dir;
395409 return ;
@@ -406,7 +420,7 @@ void showDirectory() {
406420 }
407421
408422 if (currentDirectory == currentUser->rootDirectory ) {
409- // 当前在用户根目录下,输出所有子目录名
423+ // 当前在用户根目录下,输出所有子目录名及其下所有文件名
410424 cout << " 用户 " << currentUser->username << " 根目录下的目录: " ;
411425 for (const auto & dir : currentDirectory->children ) {
412426 cout << dir->fileControlBlock ->fileName << " " ;
@@ -729,7 +743,7 @@ void moveFile(const string& filename, const string& destDir) {
729743 saveDisk (SAVE_PATH);
730744}
731745
732-
746+ // 打开文件
733747void openFile (const string& filename) {
734748 if (!currentUser) {
735749 cout << " 请先登录。" << endl;
@@ -751,7 +765,7 @@ void openFile(const string& filename) {
751765 cout << " 文件不存在。" << endl;
752766}
753767
754-
768+ // 关闭文件
755769void closeFile () {
756770 if (!currentUser) {
757771 cout << " 请先登录。" << endl;
@@ -767,6 +781,7 @@ void closeFile() {
767781 saveDisk (SAVE_PATH);
768782}
769783
784+ // 移动文件读写指针
770785void lseekFile (int offset) {
771786 if (!currentUser) {
772787 cout << " 请先登录。" << endl;
@@ -791,6 +806,7 @@ void lseekFile(int offset) {
791806 cout << " 文件不存在。" << endl;
792807}
793808
809+ // 文件加锁、解锁
794810void flockFile (const string& filename) {
795811 if (!currentUser) {
796812 cout << " 请先登录。" << endl;
@@ -812,7 +828,7 @@ void flockFile(const string& filename) {
812828 cout << " 文件不存在。" << endl;
813829}
814830
815-
831+ // 从头显示文件内容
816832void headFile (int num) {
817833 if (!currentUser) {
818834 cout << " 请先登录。" << endl;
@@ -822,12 +838,12 @@ void headFile(int num) {
822838 cout << " 当前没有打开的文件。" << endl;
823839 return ;
824840 }
825- for (const auto & file : currentDirectory->files ) {
841+ for (const auto & file : currentDirectory->files ) {// 遍历当前目录中的文件,查找打开的文件
826842 if (file->fileName == openFileName) {
827843 istringstream stream (file->content );
828844 string line;
829845 int lineCount = 0 ;
830- while (lineCount < num && getline (stream, line)) {
846+ while (lineCount < num && getline (stream, line)) {// 读取并输出前 num 行内容
831847 cout << line << endl;
832848 lineCount++;
833849 }
@@ -837,6 +853,7 @@ void headFile(int num) {
837853 cout << " 文件不存在。" << endl;
838854}
839855
856+ // 从尾显示文件内容
840857void tailFile (int num) {
841858 if (!currentUser) {
842859 cout << " 请先登录。" << endl;
@@ -851,12 +868,12 @@ void tailFile(int num) {
851868 istringstream stream (file->content );
852869 vector<string> lines;
853870 string line;
854- while (getline (stream, line)) {
871+ while (getline (stream, line)) {// 将所有行读入向量
855872 lines.push_back (line);
856873 }
857874 int totalLines = lines.size ();
858- int startLine = max (0 , totalLines - num);
859- for (int i = startLine; i < totalLines; i++) {
875+ int startLine = max (0 , totalLines - num);// 计算开始显示的行号
876+ for (int i = startLine; i < totalLines; i++) { // 输出最后 num 行内容
860877 cout << lines[i] << endl;
861878 }
862879 return ;
@@ -865,6 +882,7 @@ void tailFile(int num) {
865882 cout << " 文件不存在。" << endl;
866883}
867884
885+ // 导入文件
868886void importFile (const string& localPath, const string& virtualName) {
869887 if (!currentUser) {
870888 cout << " 请先登录。" << endl;
@@ -879,7 +897,7 @@ void importFile(const string& localPath, const string& virtualName) {
879897 cout << " 无法打开本地文件 " << localPath << endl;
880898 return ;
881899 }
882-
900+ // 读取文件内容到字符串流
883901 stringstream buffer;
884902 buffer << inFile.rdbuf ();
885903 string content = buffer.str ();
@@ -906,7 +924,7 @@ void importFile(const string& localPath, const string& virtualName) {
906924}
907925
908926
909-
927+ // 导出文件
910928void exportFile (const string& virtualName, const string& localPath) {
911929 if (!currentUser) {
912930 cout << " 请先登录。" << endl;
@@ -956,15 +974,15 @@ void userInteraction() {
956974 }
957975 getline (cin, input);
958976 {
959- std::lock_guard<std::mutex> lock (diskMutex);
977+ std::lock_guard<std::mutex> lock (diskMutex);// 加锁以确保线程安全
960978 if (input == " exit" ) {
961979 exitFlag = true ;
962980 break ;
963981 }
964- commandQueue.push (input);
982+ commandQueue.push (input);// 将命令放入队列
965983 }
966984
967- cv.notify_one ();
985+ cv.notify_one ();// 通知磁盘操作线程有新命令
968986
969987 }
970988}
@@ -973,16 +991,16 @@ void diskOperation() {
973991 while (!exitFlag) {
974992 string command;
975993 {
976- std::unique_lock<std::mutex> lock (diskMutex);
977- cv.wait (lock, [] { return !commandQueue.empty () || exitFlag; });
978- if (exitFlag && commandQueue.empty ()) break ;
979- command = commandQueue.front ();
980- commandQueue.pop ();
994+ std::unique_lock<std::mutex> lock (diskMutex);// 加锁以确保线程安全
995+ cv.wait (lock, [] { return !commandQueue.empty () || exitFlag; });// 等待新命令或退出标志
996+ if (exitFlag && commandQueue.empty ()) break ; // 如果退出标志设置且命令队列为空,则退出
997+ command = commandQueue.front ();// 获取命令
998+ commandQueue.pop ();// 移除命令
981999 lock.unlock ();
9821000 }
9831001 {
984- std::lock_guard<std::mutex> disklock (diskMutex);
985-
1002+ std::lock_guard<std::mutex> disklock (diskMutex);// 加锁以确保线程安全
1003+ // 保存当前打开文件的信息
9861004 string savedOpenFileName = openFileName;
9871005 size_t savedReadWritePointer = 0 ;
9881006 auto savedCopiedFile = copiedFile;
@@ -995,7 +1013,7 @@ void diskOperation() {
9951013 }
9961014 }
9971015 }
998-
1016+ // 重新加载磁盘
9991017 reloadDisk (SAVE_PATH);
10001018
10011019 if (!savedOpenFileName.empty ()) {
@@ -1017,7 +1035,7 @@ void diskOperation() {
10171035 if (commandTokens.empty ()) continue ;
10181036
10191037 if (!openFileName.empty ()) {
1020- // Handle file operations
1038+
10211039 if (commandTokens[0 ] == " read" ) readFile ();
10221040 else if (commandTokens[0 ] == " write" ) writeFile ();
10231041 else if (commandTokens[0 ] == " close" ) closeFile ();
0 commit comments