文件合并之前

文件合并之后

吐槽

我们项目比较奇葩, 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. a trick in reading and storing file in the exact way!

    read and write file is a very common operation regarding file mainuplation. However, the powerfull g ...

  2. ZOJ-1508Intervals(差分约束)

    题意: 有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该序列中处于[ai,bi]这个区间的整数至少有ci个.如果存在这样的序列,请求出满足题目要求的最短的序列 ...

  3. jquery 学习第一课之start

    1.$选取符 ( $ == jQuery ) (1) $("div").addClass("special");选取本页面中的所有<div>元素,然 ...

  4. HDU 4612 Warm up(手动扩栈,求树上哪两个点的距离最远)

    题目大意: 给你一个无向图,问加一条边之后最少还剩下几座桥. (注意重边处理)   分析:其实当我们把边双连通分量给求出来之后我们就能将连通块求出来,这样我们就可以重新构图.重新构造出来的图肯定是一颗 ...

  5. oracle 表查询(2)

    使用逻辑操作符号 问题:查询工资高于500 或者是岗位为MANAGER 的雇员,同时还要满足他们的姓名首字母为大写的J? or job = 'MANAGER') and ename LIKE 'J%' ...

  6. Velocity常用方法

    1.字符串替换 replace#if($!{name} != '')#set($tempName = $!{name})#set($tempName = $tempName.Replace('abc' ...

  7. iOS Block中的weakSelf/strongSelf

    Objective C 的 Block 是一个很实用的语法,特别是与GCD结合使用,可以很方便地实现并发.异步任务.但是,如果使用不当,Block 也会引起一些循环引用问题(retain cycle) ...

  8. MySQL错误代码大全

    130 :文件格式不正确.(还不是很清楚错误的状况)145  :文件无法打开.1005:创建表失败.1006:创建数据库失败.1007:数据库已存在,创建数据库失败.1008:数据库不存在,删除数据库 ...

  9. poj 2031 Building a Space Station【最小生成树prime】【模板题】

    Building a Space Station Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5699   Accepte ...

  10. javaIO流小结(1)

    UTF-8的字节占多少个字节? 常用中文字符用utf-8编码占用3个字节(大约2万多字),超大字符集中要占4个字节.在内存中是2个字节,真正写到硬盘上面的是3个字节. GBK.GB2312汉字占2个字 ...