猛禽的编程艺术

编程是一门艺术

用户操作
[即时聊天] [发私信] [加为好友]
猛禽ID:Raptor
425175次访问,排名112好友19人,关注者73
编程序——通常有BUG
写BLOG——都是些八卦
拍MM——没人给偶拍
Raptor的文章
原创 135 篇
翻译 0 篇
转载 0 篇
评论 866 篇
猛禽的公告
本站作者:猛禽
号:老鸟,别号:大叔,英文名:Raptor。

Creative Commons License
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。
联系方式:

我常用的Extensions

微笑图书室 多背一公斤

最近评论
hacker47:既然说放宽技术的视界,那么就宽到把MS的技术也能放下的程度吧,对MS有偏见,与对别的什么东西有偏见,并没有什么本质的区别。

MS是不公开源代码,但是其详尽的MSDN,个人认为使用起来比开放的源代码还好,且不说有些人的代码也不一定写的很好,是不是?

hacker47:我的观点你可能不认同,不过没关系,可以讨论。

我认为你喜欢linux是你的自由,
别人喜欢Windows也是别人的自由。

都是自由,没啥好说的。

没大见到Windows的用户说为什么linux的用户不喜欢Windows,倒是看到很多用linux的人特别讨厌Windows,不知道为什么?


kwlong2008:我是做网站建设的,来看看你的空间,不错,欢迎踩我的网站制作空间!
kwlong2008:我是做网站建设的,来看看你的空间,不错,欢迎踩我的网站制作空间!
lxd121:一旦掌握了IT技术里最重要要的语言,呵呵,楼主的问题就解决了。不过俗话说的话,达则兼济天下,所以恳请楼主们大力宣传新技术,为我等开阔视野。忘了说是什么语言,其实不说大家也都明白,呵呵
文章分类
收藏
    相册
    附图
    0. 个人链接
    1. 猛禽的河蟹BLOG(RSS)
    2. 寻找世界的美丽(RSS)
    3. Mental Studio-个人主页(RSS)
    5. 猛禽专栏-CSDN上的个人专栏
    6. 猛禽文档-CSDN个人技术文档
    7. CSDN电子报
    1. CSDN BLOG
    1. 令狐虫
    2. 韩磊(RSS)
    3. lxpbuaa(桂枝香在故国晚秋)
    4. 一竿残照.金棣@CODELPHI
    5. deadcat's blog
    6. gigix(透明思考)
    7. ozzzzzz
    8. 蝈蝈
    2. 技术BLOG
    chechy
    CoolSlob
    FrameSniper(FS)
    hkbarton
    leeon
    SnowFlacon
    小伍
    小小
    小眼镜
    我的ACE,TAO
    摩托
    百合MM
    3. 洋人BLOG
    Allen Bauer
    Anders Ohlsson
    Danny Thorpe
    Don Box
    Herb.Sutter
    James Gosling
    Martin Fowler
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 跨平台中文文件名乱码的解决收藏

    新一篇: 分布式版本控制(一) | 旧一篇: GCC的BUG研究(Rev.3)

    事情的起因是这样的~~

    在很久很久以前——大约是2年多年前,我整了一台P3的机器装了FreeBSD做服务器,经常用Filezilla的SFTP往里面备份本地的文件,当然也包括一些中文名的文件。一切都很正常,上传下载都没问题,即使是用 SSH连过去用Tar打包再Gzip压缩以后下载下来解开都没问题。

    但是好日子在前几天到头了。我前一阵又弄了一台P3的机器装了Ubuntu。问题出现了:

    首先是在Windows上用Filezilla连接Ubuntu时看到的中文文件名全是乱码,但是用Putty通过SSH连接Ubuntu却是正常 的(原先是乱码,后来改设置为UTF-8编码就好了,不过Filezilla没有类似的设置可改)。如果用Filezilla向Ubuntu上传本地的中 文文件,则在Filezilla里看到Remote端的文件名是正确的,但在Putty里看到是乱码。

    然后更严重的问题是:当我在Ubuntu上用Filezilla的SFTP从FreeBSD上下载文件时发现那些中文文件名都成了乱码。只好改用 tar/tar.gz再试,结果还是乱。最后问了Google,但是结果并不理想,试过很多方法都无法解决,甚至为此特地在FreeBSD和Ubuntu 上都装了p7zip试验,也还是不行。

    折腾了好几天之后,我才想到应该研究一下几个系统上的locale设置究竟是如何的——坦白说,要不是因为搜到的资料里有提到这方面,我从前还真没注意到这回事。在FreeBSD和Ubuntu上分别运行了locale命令检查的结果是:

    FreeBSD的LC_ALL为“C”,即”POSIX”的别名,似乎是一种无固定编码的方案,或者可以认为就是本地编码,默认的设置。
    Ubuntu的LC_ALL为“zh_CN.UTF-8”,这个是我设置的。
    Windows不必说了,肯定是本地编码——只是我没有想到的是,公司里用的英文版Windows居然也是本地编码,我一直以为是Unicode的,看来是为了保持兼容。

    这样就好理解了,Filezilla不改变编码方式,所以当Remote端与本机的编码不一致时,必然乱码。所以在Windows上用 Filezilla连接Ubuntu看到乱码,而我的Putty因为是设置为UTF-8编码,所以看到的是正确的——因为Ubuntu一端是UTF-8。 而如果用Filezilla上传中文文件,则因为Windows是本地编码,所以上传以后仍然为本地编码(GB系),而Ubuntu是UTF-8所以是乱 码。

    FreeBSD那边的问题也是一样的,因为那些文件都是以前从Windows上传上去的,用的都是GB系编码,而早年我用Putty都是用默认的本 地编码方案,所以一直没有发现问题。这样的话,因为FreeBSD是本地编码,与Ubuntu的UTF-8不一致,所以怎么弄都是乱码。

    但是据说用7zip这样的工具打包以后是可以解决这样的编码不一致问题的,我试了却没有成功。后来才想明白,因为7zip是根据系统的locale设置来对文件名进行相应的处理,因为原来我处理的时候文件名是GB系的编码,而系统是设置为UTF-8,所以总也不对。

    最后的解决方案是:

    在ubuntu上用以下命令:

    export LC_ALL="zh_CN.GBK"
    scp raptor@freebsdserver:/home/raptor/myfiles/*.* .
    export LC_ALL="zh_CN.UTF-8"
    convmv -f GBK -t UTF-8 --notest *.*

    原理就是先把ubuntu的locale改为GBK,然后用SSH COPY文件过来,再改locale为UTF-8,然后用convmv来转换文件名的编码。

    不过经过试验表明,不改变locale直接scp也是可以的,因为scp并不会改变文件名的编码方式,不过改了locale以后便于在转编码之前检查scp过来的内容(否则scp过来是乱码,要到转编码后才正常)。

    这样做的结果就是,这些文件在ubuntu上是正常了,以后要再弄回windows就比较麻烦,需要用7zip之类的工具打包下载再解开。

    归根到底这些问题都是因为该死的Windows用本地编码来记录文件名,Unicode化做得不够彻底。

    发表于 @ 2008年01月23日 10:53:00|评论(loading...)|编辑

    新一篇: 分布式版本控制(一) | 旧一篇: GCC的BUG研究(Rev.3)

    评论

    #edguo 发表于2008-01-23 18:14:33  IP: 58.251.110.*
    好久没来,你的blog更新也很慢啊 :>

    借个地方问个无聊问题,搞了我两天烦死了,知道的朋友赐教一下:

    目的是类似Delphi中的IDispath后期绑定(使用Variant)使用Invoke()调用ActiveX的指定方法。

    function IDispatch.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
    Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;

    Params实际上是PVariantArgList,在制造PVariantArgList(tagVARIANT数组)时,其他类型都可以,就是不知道怎么传递LPSTR(PChar)参数,几乎试过所有VT_XXX赋值给tagVARIANT.vt,都提示:

    "0x80020008: 不正确的变量类型。"


    Pointer赋值到Variant在Delphi是不能直接做的,间接方法都会丢失实际类型信息,没有证据证明Variant能正确记录PChar类型,但是如果真的不行的话我怀疑为什么ActiveX又能让人定义LPSTR参数方法。
    如果能提供Delphi中使用Variant向IDispatch传递含PChar/Pointer类型参数的例子也是不胜感激的,实在不行就唯有不支持这种参数或者使用VTable调用,两者都不是我想要的。

    TIA.
    #Aizz 发表于2008-01-24 20:05:35  IP: 211.136.253.*
    楼上,标准的 COM 接口参数应该是没有 LPSTR 类型的;试试 BSTR ,用 AllocSysString。

    Interface def:
    DISP_FUNCTION_ID(CMiniSTCtrl, "Open", dispidOpen, Open, VT_I4, VTS_I4 VTS_I4 VTS_I4 VTS_BSTR VTS_I4 VTS_BSTR)

    Client func:
    long Open(long nID, long nID2, long nId3, LPCTSTR bstrName, long nID4, LPCTSTR bstrName2)
    {
    long result;
    static BYTE parms[] = VTS_I4 VTS_I4 VTS_I4 VTS_BSTR VTS_I4 VTS_BSTR ;
    InvokeHelper(0x1, DISPATCH_METHOD, VT_I4, (void*)&result, parms, nID, nID2, nId3, bstrName, nID4, bstrName2);
    return result;
    }

    PS: 记得 Params 里要用逆序保存参数。
    PS: 我用 C++ ,PASCAL 不知道是不是一回事,参考吧。
    #edguo 发表于2008-01-26 10:42:08  IP: 58.251.110.*
    首先谢谢Aizz的回复,也许真的象你说的那样,“标准”的ActiveX(例如Word里面我就没看到过)是没见着用LPSTR的,而且OleVariant也是应该不支援的;不过呢,的确是可以定义类似的参数方法,其他的基本类型我试过代码都是行得通的,遇到这种参数却搞不定,现在基本上是放弃,没时间纠缠,直接发布不支持此类参数的代码,以后有空再研究。

    3q
    #Raptor 发表于2008-02-20 09:50:52  IP: 203.94.2.*
    我查了一下我以前写的代码,的确也没有处理过PCHAR类型。Aizz的方法应该可行,即先将PCHAR转换为ACTIVEX支持的类型,比如BSTR。
    #fayfarn 发表于2008-03-17 20:40:10  IP: 116.18.82.*
    是你没有弄清楚Windows下的Unicode实现方法而已,不能用Unix的实现思路来看待Windows
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 猛禽