存档

  • ExtJS4本地化

    工作后干的活有点乱七八糟,被折磨死 每一段时间就要学新的语言。2011下半年是C#,2012年,轮换到了JavaScript 最近的任务是用ExtJS设计前端,这玩意强大到足以取代Silverlight,非常适合配合RESTful API使用,使用AJAX获取JSON或XML类型的数据,前端页面的生成完全不需要PHP/JSP,仅HTML+JS已经足够。这种情况下,前端可以和API所在服务端完全分离,部署在不同的服务器上,甚至前端可以放在用户本地运行 第一个任务是攻克多语言化(老大乃将这种任务扔给素人情何以堪) 网上搜索了一下,还有人专门写了插件(ext-locale-loader),但这种需要给每一自设计的页面弄一份语言拷贝的方式让余菊花一紧 后来阅读ExtJS的自带文档,发现有本地化的详细指引($EXTJS_FOLDER/docs/index.html#!/guide/localization) 一步步来就实现了ExtJS自身的UI元件在用户选择不同语言时的本地化 实现后的效果 演示页面:extlocalize.html ExtJS语言列表RawData:languages.js(仅保留4个语言) 逻辑+UI:extlocalize.js 切换语言的逻辑其实非常简单,判断页面的传入参数(没错,静态页面也可以有参数),利用AJAX加载语言文件,然后执行语言文件中的代码,更新字符串 extlocalize.html languages.js extlocalize.js 以上仅是ExtJS UI自身的本地化。 自己系统中的文字如何本地化呢? 余的做法基本是沿着ExtJS本地化的思路,将系统用到的字符串集中在单个文件中,这也有利于后期扩展更多的语言 像Date picker/Email Field/Month Browser/Month of the year就是系统自身的语言,不应该硬编码到UI中 在加载ExtJS语言文件的时候,同时也加载系统自身的语言文件进行刷新 系统语言文件也必须使用和ExtJS语言文件相同的后缀,如en/ja/zh_CN/zh_TW 效果: 演示页面:multiplelanguages.html 逻辑+UI:multiplelanguages.js 语言列表RawData:languages.js(和上面一样) 系统默认语言文件(必须):myproject-js/myproject-lang.js(余将默认语言弄成了日文) 系统的本地化语言文件(可选):(没有参数时会保留默认语言文件中的设定) locale/myproject-lang-en.js locale/myproject-lang-ja.js locale/myproject-lang-zh_CN.js locale/myproject-lang-zh_TW.js multiplelanguages.html multiplelanguages.js 将UI的生成全部集中到setup函数里了 myproject-js/myproject-lang.js locale/myproject-lang-en.js locale/myproject-lang-ja.js locale/myproject-lang-zh_CN.js locale/myproject-lang-zh_TW.js 注意事项: 1.ExtJS库的解压目录名要一致,代码中的为ext 2.由于AJAX的本地请求会因为安全问题被浏览器禁止,需要将文件放到服务器才能测试 源文件下载:localize.rar

    113 次浏览 | 没有评论
    2012年2月3日 | 归档于 技术, 程序
  • 猜猜看:哪一种转换方法最快

    蛋疼写了三种UTF-16到UTF-8的转换方法。其中一个不出所料果然很慢,但另外的两个测试结果让余跌了一下眼镜。 直接在内存上操作速度当然快,因此converMethod中convert2utf8毫无疑问是最快的 剩下的 convert2utf8_pushback convert2utf8_copy convert2utf8_allocate 都是返回STL中的string对象,哪个最快,哪个最慢,大家来猜一下吧 convertMethod.h 测试程序:在VC新建一个工程把代码覆盖进去,并导入convertMethod.h 测试文件的路径需要更改一下,推荐用大文本测试,更能显示出性能的差异 测试文件只能是Unicode编码的文本文件 提供测试样品:bungakusyoujyo-unicode

    185 次浏览 | 2 条评论
    2011年11月8日 | 归档于 技术, 程序
    标签: , , ,
  • 使用service启动tomcat服务导致的log4j输出文字异常

    在Amazon的EC2上,用Amazon官方Linux AMI创建了一个实例,安装并配置tomcat,部署应用。 偶然一次使用service tomcat start启动服务,发现log4j输出的log中的日文字符统统变成了问号「?」。但使用/etc/init.d/tomcat启动服务却一切正常。 以前余就知道service方式启动服务会忽略掉很多环境变量,比如JAVA_HOME。 使用man命令查看帮助 [root]# man service 说是service会保留LANG和TERM两个环境变量。(事实上PATH环境变量也会传递进去) 仔细查看service脚本,却完全不是这回事。 [root]# which service /sbin/service [root]# vim /sbin/service 本来系统的默认locale是en_US.UTF-8,也即环境变量$LANG的值为en_US.UTF-8, /etc/init.d/tomcat start方式启动tomcat,除非在启动脚本中干啥坏事,否则全部的环境变量都会保留,log4j输出不会有错误 env -i命令是创建一个空白的运行环境,如果不主动传入参数,所有的环境变量都会被忽略。 Amazon官方Linux AMI的service脚本用env -i创建启动环境时,却删掉了LANG=”$LANG”,也即locale变成了POSIX,log4j输出时按POSIX输出,非ASCII字符全变成了问号 Amazon官方Linux AMI修改自CentOS,但人家CentOS的service脚本LANG保留得好好的 ubuntu的service脚本文件是/usr/sbin/service,LANG同样传递了进去 为了排查这个错误,花了一下午时间,狠命死抽Amazon 改正方法很简单,补回LANG环境变量即可 一共四处地方

    125 次浏览 | 没有评论
    2011年10月3日 | 归档于 技术
  • 动态加载字符映射表的字符转换环境方案

    余去年写Ansi2Unicode的时候,不使用win32 api进行字符转换,使用了自定义转换函数。几个不同编码的转换函数,写起来大同小异。特别是GBK和Big5,可以说是完全一样。于是很早就想开发一个动态加载字符映射表的字符转换环境,当添加新的编码时,不需要改动程序。 现在考虑到的一些特征: 1.独立于平台。Ansi2Unicode的转换函数(toUnicode.h)严重依赖MFC,通用性很差,余一直不太满意 2.字符映射表的信息保存在配置文件(charmap.xml文件),由环境动态加载。环境是一个通用环境,普适各种多字节编码 3.用户制作映射表和添加新的映射表信息遵循一定的规则 4.平台即使在运行时都可以重新载入映射表 5.字符映射表使用优先顺序由在配置文件中出现的顺序决定。用户可调整顺序 这个平台的扩展性非常强。制作映射表,修改charmap.xml,一种新的编码转换方法就添加了,有别于以前需要多写一个函数。 另外,用户还可以替换映射表,随着字符编码的升级而升级。 初步的charmap.xml配置文件

    249 次浏览 | 1 条评论
    2011年7月29日 | 归档于 技术, 程序
  • 修改旧版skydrive-gae获取skydrive外链

    wp本来有skydrive-directlink插件,但需要加[],这样的地址很多播放器不支持,并且只能局限在wp中使用。 skydrive-gae是另外一个解析skydrive链接的小程序,运行在Google App Engine上,其链接形式看起来就像一个文件,可直接喂播放器甚至下载工具。另外这种链接在需要解析时才会去解析,并且放在GAE上,不用担心影响wp性能。余大量使用这种形式做音乐试听。但上个月M$修改skydrive档案的链接格式,导致旧版skydrive-gae获取外链失效。于是决定动手改一下程序,适应变化。 旧程序使用正则表达式查找链接,被余修改后变得更加暴力。如果未来M$停止支持形如http://cid-********.skydrive.live.com/self.aspx/.Public/1.mp3的形式,怎么折腾都是没用的了,希望M$少折磨点余 新版的两个暴力函数 python不能用tab,Notepad++回车直接就是tab,查错半天没查出来 新版skydrive-gae下载,修改app.yaml中的app名称,上传到google appengine,链接的形式和旧版一样

    309 次浏览 | 4 条评论
    2011年7月5日 | 归档于 技术
  • Oracle数据库的TX锁

    以前很讨厌Oracle数据库,做DML(insert/update/delete)操作还要commit,但深入理解Oracle数据库的锁机制后,才认识到Oracle数据库的优秀和commit/rollback的合理性。Oracle数据库对并发操作的支持做得非常好,但如果不合理利用,后果同样很严重。 Oracle数据库的锁粒度上分为表级锁和行级锁,但实际上通常考虑行级锁就可以了。表级锁应用在建立表,修改表结构,建立索引,删除表等操作上,这是重大操作,一般的后台不会提供这样的权限。因此本文只谈行级锁。 行级锁仅有一个锁类型,就是TX锁。TX锁的T代表transaction,表面上一个TX锁对应一条记录,但实际上整个DML操作无论做多少遍,只要没commit,加在记录上的TX锁状态就不会改变。X代表排斥(exclusive),表级锁X不允许没持有权限的session(会话)进行任何相关表(包括表中记录)的读和写操作,但TX锁允许没持有权限的session读取记录,这涉及到Oracle副本机制,实际上session读取到的是原始记录,而非副本中的修改记录。 TX锁权限的获得方法有: 1.DML操作(insert/update/delete) 2.使用SQL语句:select *** from TableName (where ***) for update nowait; 不要小看第二种方法。 session释放当前持有的全部TX锁权限的方法有:commit和rollback。commit是合并副本到本体,rollback是抛弃副本。 启动两个Oracle SQL Plus窗口,这将是两个不同的session,可以用来模拟两个客户的行为。用这两个窗口做下面的实验,将会得出一些重要的认识。 Oracle数据库的副本机制 1.表的操作create/drop不会产生副本,倘若操作成功,作用是立刻反映到本体上。因此create和drop操作事实上无需补上commit session甲: create table test( id number(5) primary key, value NVARCHAR2(10)); session乙:select * from test; session乙没有错误产生。 session甲:drop table test; session乙:select * from test; session乙将发生错误。 重新在session甲创建test表,继续下面的实验。 Oracle数据库的sequence Oracle中的主键不会自动递增,需要手动创建sequence,插入新记录时使用sequence的nextval 2.sequence和事务无关,不需要锁。 session甲:create sequence test_seq increment by 1 start [...]

    320 次浏览 | 没有评论
    2011年4月6日 | 归档于 技术
  • 【简易教学】如何下载Google docs上的文件

    众所周知的原因,国内在访问Google docs时会被重置 绕过墙访问Google docs的方法:

    498 次浏览 | 没有评论
    2010年12月23日 | 归档于 技术
  • flac的内嵌cue提取

    flac的内嵌cue实际上有两个存放位置。按照flac官方的技术文档,flac的文件结构中METADATA_BLOCK可以存放CUESHEET类型的数据,不过这种形式的内嵌cue相当复杂,余抛弃实现提取这种cue了。另外METADATA_BLOCK还可以存放VORBIS_COMMENT类型的数据,数据部中“cuesheet=”后面的即是cue,foobar2000调用flac.exe进行编码并写入内嵌cue时,是写到VORBIS_COMMENT中。存放到VORBIS_COMMENT中似乎更普遍一点。 如果不按照flac的文件结构,用稍微暴力一点的方法提取,也是可以的,这时就和提取tak的内嵌cue非常类似了,只不过flac的位于文件头部。 简单说一下flac的METADATA_BLOCK的结构。一个METADATA_BLOCK由两部分组成,METADATA_BLOCK_HEADER和METADATA_BLOCK_DATA。METADATA_BLOCK_HEADER为固定的四字节(32bit),第一个bit为判断是否是最后一个METADATA_BLOCK,第二至第八bit为METADATA_BLOCK的类型,VORBIS_COMMENT的类型为4,后面的3个字节是METADATA_BLOCK_DATA的长度。 因为只注重内嵌cue,所以只有遇到VORBIS_COMMENT类型,才开始进行cuesheet的捕捉,否则一直跳过。跳过时文件指针移动的偏移量即是METADATA_BLOCK_DATA的长度。 代码: CueString中存放的即是utf-8编码的cue字符串,写入到文件即可。 捕捉cuesheet标记的方法和tak一样的。

    853 次浏览 | 没有评论
    2010年9月9日 | 归档于 技术, 程序
    标签: , , , , ,
  • tak的内嵌cue提取

    tak的内嵌cue提取非常简单。内嵌的cue位于文件尾部,以utf-8编码存放。只要捕捉到起始点和结束点,拷贝出来即可。 内嵌cue的起始标记是Cuesheet,大小写不敏感,结束标记是之后遇到的第一个连续终止符串(六个终止符以上) 为了不用读取整个tak文件,将文件指针移到最后20K处,将之后的数据拷贝出来,在这20K的数据中搜索。一般的cue也不会有那么长吧 CueString中存放的即是utf-8编码的cue字符串,写入到文件即可。 这自动机模型捕捉Cuesheet写得很优美(擦汗

    763 次浏览 | 没有评论
    2010年9月6日 | 归档于 技术, 程序
    标签: , , , , ,
  • tinyXml处理UTF-8编码详解——写入和读取

    以前写过一篇博文介绍tinyXml输出utf-8文档。 tinyXml的特点是不对xml节点内容的具体编码处理,这一切都交给用户。因此tinyXml和字符有关的函数都是只接受char*的数据类型。 例如: 上述代码产生的节点,如果用TiXmlDocument的SaveFile函数直接保存,只能是ANSI的本地编码(无论程序是否是unicode),即使TiXmlDeclaration指定为utf-8。一种方法是输出到TiXmlPrinter,将TiXmlPrinter.CStr()转换到utf-8编码的char*后保存。 char*在双字节编码下是一种很奇特的字符串,中文平台下的VC的编译器,char*可以存放GBK汉字,编译能正确识别字符,因为ASCII码的最高位为0,而GBK双字节字符的首字节最高位为1。 在使用utf-8字符串时,必须树立一个观念:utf-8应当只在传输时使用,不适合作为函数过程的处理对象。什么是传输场合?网络传输和文件读写。以文件读写为例,文件以utf-8编码存放,在读入到内存后,应当立刻转换为unicode宽字符串。程序的内部处理过程中只有unicode宽字符串。直到写入文件时,unicode宽字符串才转换为utf-8字符串。 utf-8字符串本身是变长字符串,并没有特定的数据类型。它是以char*形式存放,它的byte的表现不符合任何双字节编码,当成双字节编码处理会立刻出错。事实上,char*只是一个存放空间,用void*、unsigned char*本质上没有区别。(倘若你喜欢,甚至可以拿char*来存放unicode宽字符串,一次memcpy两个byte就是了)。 脱离双字节编码(如GBK)的tinyXml使用方法是存在的。 例如上述代码可以改为: UTF8Str变量名即是内含的char*字符串的起始指针。CW2A函数可以自己写一个代替,并不难实现。此时可以直接调用TiXmlDocument的SaveFile函数保存为无BOM的UTF-8文档。要保存为含BOM的UTF-8文档,仍然需要TiXmlPrinter,但此时不需要对TiXmlPrinter.CStr()进行任何处理。 tinyXml在加载xml文档时有一个标记,TiXmlDocument.LoadFile(TiXmlEncoding encoding); 这个标记没多大作用,无论设为TIXML_ENCODING_UTF8还是TIXML_ENCODING_LEGACY,读入的节点的数据类型一样是char*。 设为TIXML_ENCODING_UTF8标记的唯一作用是tinyXml会自动处理文档的BOM。 对于下面文档,怎样才能正确读取到TemplateStr节点的内容?很简单,在读取时进行转换就行。 UTF8toUnicode函数: strlen取char*的长度等于字节数(不含终止符),不是utf-8字串的真正字符个数。

    917 次浏览 | 没有评论
    2010年8月28日 | 归档于 技术, 程序
‘技术’ 分类的存档