文件合并之前

文件合并之后

吐槽

我们项目比较奇葩, ui用cocostudio做, 这项光荣的任务由美术接手.

这个美术是个新手, 经过我长时间的观察, 她似乎不用怎么画画. 至少在很长一段时间里, 她很悠闲, 只管拼UI即可.

这是我们客户端噩梦的源头.

她不懂需求, 任何ui, 只要截图下来符合策划草图就算完成任务.

因此, 什么层次结构, 什么命名规范, 统统没有.

程序接手过来的ui自己要从头到尾翻新一遍, 甚至比重做花的时间更长.

于是, 一个伟大的决定诞生了, 我把她的活一起做了, 摆脱了厄运, 让我事倍功半.

两周以后, 她说她太闲了, 又把活接了过去, 从此厄运continue..

她把每一个ui都新建一个工程, 可以看到合并前有多个目录, 容量达到500M.

而且, 同一个文件, 在不同的目录就可能是不同的名字, 总之错乱不堪, 一塌糊涂.

她的杰作, 导致apk远远过150m, 直逼200m.

就在策划, 美术大呼, 节省资源的同时, 他们依然没有意识到问题出在哪里.

随着他们的呼声越来越高, 资源也越来越大.

卧槽, 彻底服了.

实际行动

终于, 我忍无可忍了, 决定要彻底优化一次资源.

由于资源文件太乱, 根本无从下手, 于是我订好了目录结构, 统一了文件名, 把这个活交给了美术.

这个事情很容易完成, 因为他们只要整理文件就OK, 至于ui资源里指定的文件路径, 都是由程序各自去修改.

所以, 这个工作量是相当的小, 我以为美术一周内怎么也可以做完了...

2个月以后, 美术把文件整理好了.

然后我把文件合并了, 有效资源居然只有22m.

源码

 #include <Windows.h>
 #include <windowsx.h>

 #include <string>
 #include <memory>
 #include <utility>
 #include <vector>
 #include <fstream>
 #include <list>
 #include <iterator>
 #include <functional>
 #include <iostream>
 #include <thread>
 #include <regex>

 #define LOG(param)    {std::wcout << param << std::endl;}

 size_t getFileSize(std::wifstream &ifile)
 {
     ifile.seekg(, std::ios::end);
     auto pos = (size_t)ifile.tellg();
     ifile.seekg(, std::ios::beg);
     return pos;
 }

 //    获得目录.
 inline std::wstring getDirectoryName(const std::wstring &fullName)
 {
     auto pos = fullName.find_last_of(L'\\');
     , pos) : L"";
 }
 //    获得文件名.
 inline std::wstring getFileName(const std::wstring &fullName)
 {
     auto pos = fullName.find_last_of(L'\\');
     ) : L"";
 }
 //    获取后缀.
 inline std::wstring getFileExtName(const std::wstring &fullName)
 {
     auto pos = fullName.find_last_of(L'.');
     ) : L"";
 }

 class Project {
 public:
     std::wstring directoryName;
     std::wstring directoryPath;
     std::wstring jsonPath;
     std::wstring projectName;
     std::vector<std::wstring> jsonList;
 };

 bool handleFileList(const std::wstring &rootDirectory, const std::wstring &outDirectory, const std::vector<std::wstring> &fileList)
 {
     auto result = false;
     LOG("handleFileList");
     std::vector<Project> projectList;

     {
         Project project;
         for (auto &fullName : fileList)
         {
             auto directoryPath = getDirectoryName(fullName);
             auto fileName = getFileName(fullName);
             auto extName = getFileExtName(fileName);

             if (extName == L"ui" && directoryPath != project.directoryPath)
             {
                 //    记录路径.
                 if (!project.directoryPath.empty())
                 {
                     projectList.push_back(project);
                 }
                 project = Project();
                 project.directoryPath = directoryPath;
                 project.directoryName = getFileName(directoryPath);
                 project.jsonPath = directoryPath + L"\\Json";
             }

             //    记录项目文件名.
             if (extName == L"ui")
             { project.projectName = fileName; }

             //    记录项目的json文件名.
             if ( getFileName(directoryPath) == L"Json" && extName == L"json")
             {
                 project.jsonList.push_back(fileName);
             }
         }
     }

     //    生产新的项目.
     {
         //    cat json file.
         std::wstring jsonList;

         CreateDirectory( (outDirectory + L"\\Json").c_str(), nullptr );
         CopyFile(L"null_project\\Json\\null_project_1.json", (outDirectory + L"\\Json\\null_project_1.json").c_str(), FALSE);

         for (auto &project : projectList)
         {
             for (auto &json : project.jsonList)
             {
                 auto name = project.directoryName + L"_" + json;
                 auto inName = project.jsonPath + L"\\" + json;
                 auto outName = outDirectory + L"\\Json\\" + name;
                 auto copy = CopyFile(inName.c_str(), outName.c_str(), FALSE);
                 jsonList.append(L"<string>" + name + L"</string>\n");
                 LOG(L"copy " << inName << L", " << outName << L" | " << copy);
             }
             LOG(L"copy resources.");
             wchar_t commandLine[] = {  };
             auto inName = project.directoryPath + L"\\Resources";
             auto outName = outDirectory + L"\\Resources";
             wsprintf(commandLine, L"/c xcopy %s\\*.* %s\\ /E /Y", inName.c_str(), outName.c_str());
             ShellExecute(nullptr, L"open", L"cmd", commandLine, nullptr, SW_SHOW);
         }

         do {
             //    写入 project.
             std::wifstream ifile(L"null_project\\null_project.xml.ui", std::ios::binary | std::ios::in);
             if (!ifile)
             {
                 break;
             }
             auto fileSize = getFileSize(ifile);
             auto templateBuffer = std::wstring(fileSize, L'\0');
             ifile.read(&templateBuffer[], fileSize);
             ifile.close();

             auto writeStr = std::regex_replace(
                 templateBuffer, std::wregex(L"JsonList_Replace"), jsonList);
             std::wfstream ofile(outDirectory + L"\\project.xml.ui", std::ios::binary | std::ios::out);
             ofile.write(writeStr.c_str(), writeStr.size());
             ofile.close();
         } );

         result = true;
     }
     return result;
 }

 bool run(const std::wstring &rootDirectory, const std::wstring &outDirectory)
 {
     auto result = false;

     do {
         {
             wchar_t commadBuffer[];
             wsprintf(commadBuffer,
                      L"/c "
                      L"%c:&"
                      L"cd %s&"
                      L"del config.txt&"
                      L"for /R %%i in (*) do (echo %%i>>%s\\config.txt)",
                      rootDirectory[], rootDirectory.c_str(), rootDirectory.c_str());
             ShellExecute(nullptr, L"open", L"cmd", commadBuffer, nullptr, SW_SHOW);
             LOG(L"Wait 10 Seconds...");
             std::this_thread::sleep_for(std::chrono::milliseconds());
         }

         //    打开文件
         std::wifstream ifile(rootDirectory + L"\\config.txt");

         //    读取文件列表.
         std::vector<std::wstring> fileList;
         if (ifile)
         {
             LOG(L"open config.txt.");
             do {
                 std::wstring fileName;
                 std::getline(ifile, fileName);
                 fileList.push_back(fileName);
             } while (!ifile.eof());
             ifile.close();
             LOG(L"init file list.");
         }

         if (!fileList.empty())
         {
             result = handleFileList(rootDirectory, outDirectory, fileList);
         }
     } );

     return result;
 }

 int main()
 {
     std::locale::global(std::locale("chs"));

     std::wifstream ifile(L"config.txt");
     if (ifile)
     {
         std::wstring rootDirectory = L"X:\\Output\\office\\UI\\11月新版UI";
         std::wstring outDirectory = L"X:\\Output\\test_out";
         std::getline(ifile, rootDirectory);
         std::getline(ifile, outDirectory);

         std::wcout
             << L"rootDirectory: " << rootDirectory << L"\n"
             << L"outDirectory: " << outDirectory << std::endl;
         std::wcout << (run(rootDirectory, outDirectory) ? L"done." : L"failed.");
     }
     std::wcout << L"\n===========================end.===========================\n";
     std::cin.get();
     ;
 }

思路比较简单, 效果看起来很高端有没有.

一堆的控制台弹窗.

好久没写博客了, 今天坐一会标题党.

cocos2dx 资源合并.的更多相关文章

  1. 前端性能优化成神之路—资源合并与压缩减少HTTP请求

    资源合并与压缩减少HTTP请求的概要 资源合并与压缩减少HTTP请求主要的两个优化点是减少HTTP请求的数量和减少请求资源的大小 http协议是无状态的应用层协议,意味着每次http请求都需要建立通信 ...

  2. 资源合并fis-postpackager-simple插件的使用

    FIS默认只会进行文件打包,不会对页面中的静态资源引用进行替换,这时可以利用fis-postpackager-simple插件进行资源替换. 安装: npm install -g fis-postpa ...

  3. FIS常用功能之资源合并

    这节讲资源合并,实战目录如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  4. cocos2dx资源和脚本加密quick-lua3.3final

    一.资源加密 版本号:Quick-Cocos2d-x 3.3 Final 调试工具:xCode 工程创建的时候选择的拷贝源码. 项目结构如图: 这个功能七月大神在很早之前就已经实现了,但是在3.3版本 ...

  5. web站点优化之使用tengine搭建静态资源服务器,静态资源合并加载案例剖析

    在一个项目还是单体架构的时候,所有的js,css,image都会在一个web网站上,看起来并没有什么问题,比如下面这样: 但是当web网站流量起来的时候,这个单体架构必须要进行横向扩展,而在原来的架构 ...

  6. 网络加速手段之一,JS文件资源合并下载

    有过ftp下载文件经验的人都有体验,单独下载一个100M的文件比分开下载100个1M的文件速度快很多,这是因为下载需要解析域名,建立连接等额外开销的时间,因此下载100个文件就要做100次这种额外的开 ...

  7. cocos2d-x 资源路径研究

    调用cc.FileUtils:getInstance():addSearchResolutionsOrder("src"); 加入�一个搜索路径,就能够直接载入src文件夹下的资源 ...

  8. 使用nginx-http-concat添加nginx资源请求合并功能

    web项目中有时候一个页面会加载多个js或css资源请求,导致页面加载耗时较长,这时优化的方向可以采用资源合并,可以在客户端事先合并,也可以在服务端进行资源合并,服务端合并的方式使用起来更灵活. ng ...

  9. Mvc 之System.Web.Optimization 压缩合并如何让*.min.js 脚本不再压缩

    最近项目中用到了easy ui ,但是在配置BundleConfig 的时候出现了问题,easy ui的脚本jquery.easyui.min.js 压缩后出现各种脚本错误,总是莫名其妙的 i标量错误 ...

随机推荐

  1. Qt入门(14)——父窗口部件和子窗口部件

    这个例子演示了如何创建一个父窗口部件和子窗口部件.我们下面使用一个单一的父窗口部件和一个独立的子窗口部件编写界面.    #include <qvbox.h>我们添加了一个头文件qvbox ...

  2. 高效算法——Bin Packing F - 贪心

      Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Descripti ...

  3. cf602A Two Bases

    A. Two Bases time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  4. entityframework分布式事务中遇到的 “与基础事务管理器的通信失败”的解决方法

    首先是ef的多数据库操作实现事务的方法 public int AddDifferenceDB(userinfo1 user1, userinfo user) { ; using (var test2D ...

  5. SRM 393(1-250pt)

    题意:有m个人投票,每个人在心里对所有候选者排了一个序,比如“210”,则他最想投2号,如果2号已经出局他会投1号,最后投0号,否则弃权不投.选举时进行多轮投票,知道选出winner或者所有人均出局. ...

  6. <离散数学>学习笔记1--逻辑和证明

    今天开始离散数学的自学旅程. 主题:逻辑和证明 逻辑规则给出数学语句的准确含义.逻辑对计算机科学有着重要作用.为了理解数学,我么必须理解正确的数学论证是由什么组成的.只要证明一个数学语句是真的,我们就 ...

  7. Linux 下让进程在后台可靠运行的几种方法

    想让进程在断开连接后依然保持运行?如果该进程已经开始运行了该如何补救? 如果有大量这类需求如何简化操作? 我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一 ...

  8. DNA Sequence - POJ 2778(AC自动机+矩阵乘法)

    题目大意:DNA序列是有 ATGC 组成的,现在知道一些动物的遗传片段有害的,那么如果给出这些有害的片段,能否求出来所有长度为 N 的基因中有多少是不包含这些有害片段的.   分析:也是断断续续做了一 ...

  9. solr 在windows下的安装

    安装环境 Windows 7 64bit Apache-tomcat-8.0.9-windows-x64 Solr-4.9.0 JDK 1.8.0_05 64bit 安装步骤 Tomcat和JDk的安 ...

  10. CreateFont具体解释

    CFont * f;    f = new CFont;    f->CreateFont(10, // nHeight         0, // nWidth         0, // n ...