文件合并之前

文件合并之后

吐槽

我们项目比较奇葩, 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. 2015 BJOI 0102 Secret

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=477 试题描述: 在 MagicLand 这片神奇的大陆上,有样一个古老传说 ...

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

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

  3. cgic: CGI的C函数库

    下载回源码包以后,就3个文件:cgic.c      函数库capture.c   一个很简单的CGI例子,仅仅输出两行提示文字cgictest.c  一个演示读取form表单数据的CGI例子 首先在 ...

  4. 图论(二分图最大权独立点集):COGS 2051. 王者之剑

    2051. 王者之剑 ★★★☆   输入文件:Excalibur.in   输出文件:Excalibur.out   简单对比 时间限制:1 s   内存限制:256 MB [题目描述] 这是在阿尔托 ...

  5. JQuery固定表头插件fixedtableheader源码注释

    在开发XX车站信息系统时,需要将大量数据显示在一个巨大的表格内部,由于表格是一个整体,无法分页,加之数据很多,超出一屏,为了方便用户,决定使用固定表头的插件,经过测试,发现JQuery 插件:fixe ...

  6. 调试中除了在URL上加时间戳外,如何避免js、css被返回304状态?

    在本地开发环境(nginx)中,经常遇到这样的情况:调试js时浏览器总是不载入已修改的js内容,而直接吐出了上次缓存的代码.   我曾经做过以下尝试: ctrl+F5 ctrl+F5+F5+F5+F5 ...

  7. bzoj 1010 [HNOI2008]玩具装箱toy(DP的斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7874  Solved: 3047[Submit][St ...

  8. openStack images

  9. How many ways?? - hdu2157(矩阵快速幂-模板)

    分析:求Map^k,刚开始没有用快速幂,TLE了   代码如下: =================================================================== ...

  10. Spring入门一

    一 简介 1.Spring为企业应用的开发提供了一个轻量级的解决方案,该解决方案包括:基于依赖注入的核心机制.基于AOP的声明式事务管理.与多种持久层技术 的整合,以及优秀的Web MVC框架等等.可 ...