关于自动识别文本流的编码方式

上周遇到一件很讨厌的事情,我设计的那个WEB项目,按计划是在中文系统下进行开发的,但是突然起了点变故要回到日文系统下开发。本来就是一个中文的应用,一开始设计Demo的时候几十个HTML页面文件用的都是GB2312编码,就为了照顾公司的一些狗屁规定不得不又将它们改成UTF-8编码。
 
如果说一个一个用UltraEdit来转码的话,简直是把人当驴子用了,同时考虑到另一项目的源代码文件需要经常在EUC和SHIFT-JIS编码间来回转换,一狠心,自己用C#写了一个批量文本文件编码转换工具,原理很简单,就是递归遍历一个指定的目录,将所有指定扩展名的文件列表取回,再分别在循环里将每个文件按照指定的编码读入为字符串,然后将该字符串转换为目标的编码格式并存盘。所用API非常简单,分别有:
  • System.Text.Encoding
  • System.IO.StreamReader(指定Encoding)
  • System.IO.StreamWriter(指定Encoding)
期间考虑到一个问题,自然就是现在讨论的自动识别源文件的编码方式了。当时没有时间做深入调出,我想,要做这个工作算法定然比较复杂,因为文本文件所用的编码格式并不是明文记录在文件头或文件尾信息的(UTF例外),如果要做的话,似乎也只能根据字节排列特征来估算出所用的编码格式,既然是估算,那么必然就有一个相似度的问题导致估算结果不可能百分之百准确无误。平常用Word打开一些非ASCII文本文件的时候就发现过,Word的自动识别功能只能提供一个最接近的答案,具体则让用户自己选择,还有IE自动识别网页流的时候也是一样不可能完全正确,但是两者的正确率毕竟是非常高的。
 
今天周末闲来无事,突然想调查一下这个问题。Google了一下,首先发现有人将Mozilla的编码识别组件源代码移植到了Java上,项目名叫做[jchardet],在http://sourceforge.net/上可以找到。另外http://www.codeproject.com/上有人借助IE的IMultiLanguage2接口提供的编码识别功能,使用C#实现了这一愿望,文章标题[Detect Encoding for in- and outgoing text]。真是世上无难事只怕有心人了。
 
另外,期间还有两个衍生出来的问题,其一是UNIX<==>DOS文件格式的互相转换,对于这个小工具来说非常容易,只需要使用StreamReader按行读取文本文件,这样就会丢弃原有的换行格式(DOS的0D0A或UNIX的0A),在使用StringBuilder拼接字符串的时候给每行按照要求追加0D0A或0A作为换行格式就可以了。
 
其二是识别二进制文件或文本文件,这个问题的解决方案很让人无奈,因为归根到底文本文件依然是二进制文件,算法上来说,必须按字节遍历整个文件的每一个字节,如果发现有字节值小于32并且不是[/r/n/t/p]四字符中任何一个字符的文件,就可以认为是二进制文件。算法很简单,不过考虑到遍历文件的效率问题,在该工具里还是放弃了这个功能,因为在文件输入的时候已经按照指定的扩展名作了过滤而且对文件大小作了限制,除非有人故意捣蛋的话是不会去把一个二进制文件当成文本文件处理的。
总的来说,发现文件的编码格式居然也是一个很有趣的课题。
 
2007-10-07后记:文本流字符编码识别的源代码本人已经上传到CSDN资源上,可以参考(http://download.csdn.net/source/259091)。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值