文件合并之前

文件合并之后

吐槽

我们项目比较奇葩, 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. struts2 Convention插件零配置,使用注解开发

    从struts21开始,struts2不再推荐使用codebehind作为零配置插件,而是改用Convention插件来支持零配置.与以前相比较,Convention插件更彻底. 使用Conventi ...

  2. left join 、right join 、inner join和 full join的区别

    内连接      INNER JOIN(等值连接):只显示两个表中联结字段相等的行.这个和用select查询多表是一样的效果,所以很少用到: 外连接:LEFT JOIN :以左表为基础,显示左表中的所 ...

  3. HDU Collect More Jewels 1044

    BFS + 状态压缩 险过 这个并不是最好的算法 但是写起来比较简单 , 可以AC,但是耗时比较多 下面是代码 就不多说了 #include <cstdio> #include <c ...

  4. 关于sed中的Pattern Space和Hold Space的随笔

    首先是一部分概念和示例,这部分转自:http://coolshell.cn/articles/9104.html Pattern Space 第零个是关于-n参数的,大家也许没看懂,没关系,我们来看一 ...

  5. iOS: 关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系

    刚接触iOS开发的人难免会对苹果的各种证书.配置文件等不甚了解,可能你按照网上的教程一步一步的成功申请了真机调试,但是还是对其中的缘由一知半解.这篇文章就对Certificate.Provisioni ...

  6. 什么是Socket,为什么要用Socket

    应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据.为了区别不同的应用程序进程和连接 ...

  7. 多台计算机之间的ssh无密钥登录

    在很多分布式系统中,我们最常遇到的一个问题是,需要在服务器集群上保证多台机器之间的SSH无密钥登录.以Hadoop为例,为了方便,我们需要在master和slaves之间配置密钥登录,这样我们启动Ha ...

  8. Eclipse Python配置

    Macbook上面安装pydev后,发现新建project后并没有PyDev的选项.在官网上搜索后发现是JDK版本太久.上Oracle官网下载了最新JDK(url: http://www.oracle ...

  9. Monkeyrunner入门示例

    准备工作1.安装Android SDK2.熟悉MonkeyRunner的API(http://article.yeeyan.org/view/37503/164523)3.一部Android手机或模拟 ...

  10. UNDERSTANDING VOLATILE VIA EXAMPLE--reference

    We have spent last couple of months stabilizing the lock detection functionality in Plumbr. During t ...