文件合并之前
文件合并之后
吐槽
我们项目比较奇葩, ui用cocostudio做, 这项光荣的任务由美术接手.
这个美术是个新手, 经过我长时间的观察, 她似乎不用怎么画画. 至少在很长一段时间里, 她很悠闲, 只管拼UI即可.
这是我们客户端噩梦的源头.
她不懂需求, 任何ui, 只要截图下来符合策划草图就算完成任务.
因此, 什么层次结构, 什么命名规范, 统统没有.
程序接手过来的ui自己要从头到尾翻新一遍, 甚至比重做花的时间更长.
于是, 一个伟大的决定诞生了, 我把她的活一起做了, 摆脱了厄运, 让我事倍功半.
两周以后, 她说她太闲了, 又把活接了过去, 从此厄运continue..
她把每一个ui都新建一个工程, 可以看到合并前有多个目录, 容量达到500M.
而且, 同一个文件, 在不同的目录就可能是不同的名字, 总之错乱不堪, 一塌糊涂.
她的杰作, 导致apk远远过150m, 直逼200m.
就在策划, 美术大呼, 节省资源的同时, 他们依然没有意识到问题出在哪里.
随着他们的呼声越来越高, 资源也越来越大.
卧槽, 彻底服了.
实际行动
终于, 我忍无可忍了, 决定要彻底优化一次资源.
由于资源文件太乱, 根本无从下手, 于是我订好了目录结构, 统一了文件名, 把这个活交给了美术.
这个事情很容易完成, 因为他们只要整理文件就OK, 至于ui资源里指定的文件路径, 都是由程序各自去修改.
所以, 这个工作量是相当的小, 我以为美术一周内怎么也可以做完了...
2个月以后, 美术把文件整理好了.
然后我把文件合并了, 有效资源居然只有22m.
源码
1 #include <Windows.h> 2 #include <windowsx.h> 3 4 #include <string> 5 #include <memory> 6 #include <utility> 7 #include <vector> 8 #include <fstream> 9 #include <list> 10 #include <iterator> 11 #include <functional> 12 #include <iostream> 13 #include <thread> 14 #include <regex> 15 16 #define LOG(param) {std::wcout << param << std::endl;} 17 18 size_t getFileSize(std::wifstream &ifile) 19 { 20 ifile.seekg(0, std::ios::end); 21 auto pos = (size_t)ifile.tellg(); 22 ifile.seekg(0, std::ios::beg); 23 return pos; 24 } 25 26 // 获得目录. 27 inline std::wstring getDirectoryName(const std::wstring &fullName) 28 { 29 auto pos = fullName.find_last_of(L‘\\‘); 30 return pos != std::wstring::npos ? fullName.substr(0, pos) : L""; 31 } 32 // 获得文件名. 33 inline std::wstring getFileName(const std::wstring &fullName) 34 { 35 auto pos = fullName.find_last_of(L‘\\‘); 36 return pos != std::wstring::npos ? fullName.substr(pos + 1) : L""; 37 } 38 // 获取后缀. 39 inline std::wstring getFileExtName(const std::wstring &fullName) 40 { 41 auto pos = fullName.find_last_of(L‘.‘); 42 return pos != std::wstring::npos ? fullName.substr(pos + 1) : L""; 43 } 44 45 class Project { 46 public: 47 std::wstring directoryName; 48 std::wstring directoryPath; 49 std::wstring jsonPath; 50 std::wstring projectName; 51 std::vector<std::wstring> jsonList; 52 }; 53 54 bool handleFileList(const std::wstring &rootDirectory, const std::wstring &outDirectory, const std::vector<std::wstring> &fileList) 55 { 56 auto result = false; 57 LOG("handleFileList"); 58 std::vector<Project> projectList; 59 60 { 61 Project project; 62 for (auto &fullName : fileList) 63 { 64 auto directoryPath = getDirectoryName(fullName); 65 auto fileName = getFileName(fullName); 66 auto extName = getFileExtName(fileName); 67 68 if (extName == L"ui" && directoryPath != project.directoryPath) 69 { 70 // 记录路径. 71 if (!project.directoryPath.empty()) 72 { 73 projectList.push_back(project); 74 } 75 project = Project(); 76 project.directoryPath = directoryPath; 77 project.directoryName = getFileName(directoryPath); 78 project.jsonPath = directoryPath + L"\\Json"; 79 } 80 81 // 记录项目文件名. 82 if (extName == L"ui") 83 { project.projectName = fileName; } 84 85 // 记录项目的json文件名. 86 if ( getFileName(directoryPath) == L"Json" && extName == L"json") 87 { 88 project.jsonList.push_back(fileName); 89 } 90 } 91 } 92 93 // 生产新的项目. 94 { 95 // cat json file. 96 std::wstring jsonList; 97 98 CreateDirectory( (outDirectory + L"\\Json").c_str(), nullptr ); 99 CopyFile(L"null_project\\Json\\null_project_1.json", (outDirectory + L"\\Json\\null_project_1.json").c_str(), FALSE); 100 101 for (auto &project : projectList) 102 { 103 for (auto &json : project.jsonList) 104 { 105 auto name = project.directoryName + L"_" + json; 106 auto inName = project.jsonPath + L"\\" + json; 107 auto outName = outDirectory + L"\\Json\\" + name; 108 auto copy = CopyFile(inName.c_str(), outName.c_str(), FALSE); 109 jsonList.append(L"<string>" + name + L"</string>\n"); 110 LOG(L"copy " << inName << L", " << outName << L" | " << copy); 111 } 112 LOG(L"copy resources."); 113 wchar_t commandLine[1024] = { 0 }; 114 auto inName = project.directoryPath + L"\\Resources"; 115 auto outName = outDirectory + L"\\Resources"; 116 wsprintf(commandLine, L"/c xcopy %s\\*.* %s\\ /E /Y", inName.c_str(), outName.c_str()); 117 ShellExecute(nullptr, L"open", L"cmd", commandLine, nullptr, SW_SHOW); 118 } 119 120 do { 121 // 写入 project. 122 std::wifstream ifile(L"null_project\\null_project.xml.ui", std::ios::binary | std::ios::in); 123 if (!ifile) 124 { 125 break; 126 } 127 auto fileSize = getFileSize(ifile); 128 auto templateBuffer = std::wstring(fileSize, L‘\0‘); 129 ifile.read(&templateBuffer[0], fileSize); 130 ifile.close(); 131 132 auto writeStr = std::regex_replace( 133 templateBuffer, std::wregex(L"JsonList_Replace"), jsonList); 134 std::wfstream ofile(outDirectory + L"\\project.xml.ui", std::ios::binary | std::ios::out); 135 ofile.write(writeStr.c_str(), writeStr.size()); 136 ofile.close(); 137 } while (0); 138 139 140 141 result = true; 142 } 143 return result; 144 } 145 146 bool run(const std::wstring &rootDirectory, const std::wstring &outDirectory) 147 { 148 auto result = false; 149 150 do { 151 { 152 wchar_t commadBuffer[256]; 153 wsprintf(commadBuffer, 154 L"/c " 155 L"%c:&" 156 L"cd %s&" 157 L"del config.txt&" 158 L"for /R %%i in (*) do (echo %%i>>%s\\config.txt)", 159 rootDirectory[0], rootDirectory.c_str(), rootDirectory.c_str()); 160 ShellExecute(nullptr, L"open", L"cmd", commadBuffer, nullptr, SW_SHOW); 161 LOG(L"Wait 10 Seconds..."); 162 std::this_thread::sleep_for(std::chrono::milliseconds(10000)); 163 } 164 165 // 打开文件 166 std::wifstream ifile(rootDirectory + L"\\config.txt"); 167 168 // 读取文件列表. 169 std::vector<std::wstring> fileList; 170 if (ifile) 171 { 172 LOG(L"open config.txt."); 173 do { 174 std::wstring fileName; 175 std::getline(ifile, fileName); 176 fileList.push_back(fileName); 177 } while (!ifile.eof()); 178 ifile.close(); 179 LOG(L"init file list."); 180 } 181 182 if (!fileList.empty()) 183 { 184 result = handleFileList(rootDirectory, outDirectory, fileList); 185 } 186 } while (0); 187 188 return result; 189 } 190 191 int main() 192 { 193 std::locale::global(std::locale("chs")); 194 195 std::wifstream ifile(L"config.txt"); 196 if (ifile) 197 { 198 std::wstring rootDirectory = L"X:\\Output\\office\\UI\\11月新版UI"; 199 std::wstring outDirectory = L"X:\\Output\\test_out"; 200 std::getline(ifile, rootDirectory); 201 std::getline(ifile, outDirectory); 202 203 std::wcout 204 << L"rootDirectory: " << rootDirectory << L"\n" 205 << L"outDirectory: " << outDirectory << std::endl; 206 std::wcout << (run(rootDirectory, outDirectory) ? L"done." : L"failed."); 207 } 208 std::wcout << L"\n===========================end.===========================\n"; 209 std::cin.get(); 210 return 0; 211 }
思路比较简单, 效果看起来很高端有没有.
一堆的控制台弹窗.
好久没写博客了, 今天坐一会标题党.
时间: 2024-11-05 06:25:54