iconv -f UTF- -t gb18030 file_input -o file_output

上述命令不一定有用。

大概了解下文件编码,和vim里面的编码情况。

1 字符编码基础知识

字符编码是计算机技术中最基本和最重要的知识之一。如果缺乏相关知识,请自行恶补之。这里仅做最简要的说明。

1.1 字符编码概述

所谓的字符编码,就是对人类发明的每一个文字进行数字化表示。最经典的ASCII编码就是西方人发明的针对英文字符的编码方法,包括26个英文字母、数字、标点、特殊字符等。问题是,这种编码的范围是0-127,只能对128个字符进行编码。当计算机来到其他国家后发现,除了英语,还有大量的其他语言,而且涵盖的字符也远远多于128个。为此,各个国家开始针对自己的语言进行编码工作,例如中国的GBK,日本的CJK,等等。

这虽然解决了ASCII编码不够用的问题,但是却带来了另外一个更加严重的问题。那就是各个国家的字符编码不统一,导致无法进行统一处理。于是乎,著名的UNICODE出现了,UNICODE编码范围非常大,可以涵盖全球所有语言的字符。

1.2 区分字符集(Charset)和字符编码(Char Encoding)

这两个术语有时候不进行区分的使用,但是理解其区别对于理解字符编码至关重要。

  • 代码点(Code Point) 
    也就是我们前面说到的,为每一个字符分配一个数字序号。例如在ASCII字符集中,字符A被分配成65号,那就是说A的代码点是65。一种编码规范中,所有的代码点的集合就是字符集。

  • 字符编码 
    字符编码是代码点的二进制存储格式。还是前面的例子,在ASCII字符集中,A的代码点是65。而这个65究竟是怎么用二进制0和1序列表示呢?这就是字符编码的工作。在ASCII编码中,这个65被存储为01000001,一共占据一个字节(8个二进制位)。

说到这里也许你会觉得,这中区别也没什么啊,这主要是因为在我们的例子中ASCII字符集的代码点只有一种字符编码方式,也就是ASCII字符编码。而这在其他字符集中却不总是这样,例如UNICODE字符集。

UNICODE字符集,规定了全球每一个字符的代码点,例如英文字母A在UNICODE字符集中的代码点是65(哈哈,这个代码点与ASCII是兼容的),然而65的存放格式却有很多方式:例如在UTF-8字符编码规范中被存储为8个二进制位:01000001,而在UCS-16中被存储为16个二进制位:0000000001000001,而在UCS-32中被存储为32个二进制位:00000000000000000000000001000001。

说到这里,就明白了,UNICODE字符集对应有很多不同的字符编码方式:UTF-8,UCS-16,UCS-32等等。 
而ASCII字符集只有一种编码方式:ASCII字符编码。

UNICODE字符集的不同编码方式是为了适应不同的环境而被创造出来的,例如UTF-8被用来网络传输,文件存放,UCS-16则被用来作为内存中的存放方式,以利于快速统一计算。

现如今,虽然UNICODE字符集已经获得广泛采用,然而历史遗留的其他字符集仍大量存在。 
近年来,字符集的概念很少被提及,字符编码则更多的被使用。

1.3 字符编码与显示

对字符进行编码只是完成了存放、处理和传输,要想把字符的形状绘制出来,还要有对应的字体以及渲染手段。

对于GUI程序,操作系统都会提供API来对指定字符进行渲染绘制。对于终端来说,终端有一个字符编码的属性,从而把接收到的二进制字节流按照这个字符编码进行解析,然后调用相应的渲染引擎来对其进行显示,详情请参考我的一篇博文:从调用printf()到显示器上看到字符串。

2 VIM读取、显示、保存文本文件过程分析

2.1 VIM涉及到的字符编码

(1) 磁盘文件的字符编码 
存放在磁盘上的文本文件,是按照一定的字符编码进行保存的,不同的文件可能使用了不同的字符编码。 
这在VIM中被叫做:fileencoding。

(2) VIM缓冲区以及界面的字符编码 
VIM运行时,其菜单、标签、以及各个缓冲区统一使用一种字符编码方式。 
这在VIM中被叫做:encoding。

(3) 终端使用的字符编码 
终端同一时刻只能使用一种字符编码,并按照这种编码从接收到的字节流中识别字符,并显示,终端的字符编码是可以动态调整的。 
这在VIM中被叫做:termencoding。

2.2 vim读、显、存分析

(1)读文件 
VIM打开文件时,并不知道文件的字符编码,所以不得不进行探测。探测是按照一定的优先顺序进行测试。依据的标准就是:fileencodings。VIM逐一测试fileencodings变量指定的字符编码方式,直到找到认为合适的然后把这种字符编码方式设置为fileencoding变量。

然后把文件中的编码转换成encoding指定的编码方式,存入文件缓冲区中。 
(2)显示文件 
vim把文件读取完毕并以encoding编码存放到缓冲区内存之后,会根据termencoding指定的终端编码方式,转换成termencoding编码后,写入到终端。此时,终端按照自身的编码属性识别出一个个的字符,调用渲染引擎绘制到屏幕上。

(3)保存文件 
VIM把缓冲区中的encoding编码的字节集合转换成fileencoding编码后写入磁盘,完成文件保存。

可以看出,VIM涉及到的3种字符编码之间的转换: 
读:fileencoding—–> encoding 
显:encoding ——> termencoding 
写:encoding ——-> fileencoding

只要这三种转换都不会出现问题,那么VIM就可以正常工作,不会出现乱码。 
然而,并不是所有的字符编码之间都能够无损转换,例如GBK字符编码转换为ASCII编码时,由于ASCII并不能完全包含GBK的字符,所以会出现问题。

3 常见乱码情况分析

3.1 读文件时,VIM探测fileencoding不准确

这很好理解,比如以GBK编码方式存储的文件,VIM把fileencoding探测成了ASCII,则肯定会出现问题。

【解决方法】一是靠VIM自身提高探测水平;二是设置合适的fileencodings变量,把最可能用到的编码方式放到最前面。如果VIM实在是探测不对,那么就只能通过 :set fileencoding=xxx 命令来手动探测了。

3.2 fileencoding编码无法正确转换到encoding编码

例如,文件采用GBK编码,而ecoding使用ASCII,这样大量的汉字字符无法被转换,从而导致乱码。 
【解决方法】把encoding设置成UTF-8,目前为止UTF-8能包含所有字符,所以其他的任何编码方式都可以无损的转换为UTF-8。

3.3 encoding无法正确转换到termencoding

这个问题,与3.2类似。 
【解决办法】把termencoding设置为何encoding相同。默认termencoding=”“的情况下,这两者就是相同的。

3.3 termencoding与实际的终端字符编码不一致

例如本来字符终端的编码属性为GBK,而termencoding却为UTF-8,那么VIM就会错误的认为终端就是UTF-8编码的,导致向终端输出UTF-8编码的字节流,而终端却按照GBK来识别,当然就会识别成乱码。 
【解决办法】把终端实际的编码方式和VIM的termencoding统一起来。

3.4 终端显示能力欠缺

例如,传统的字符终端,本身不具备显示汉字的能力,虽然它可以识别出UTF-8编码的汉字,但是渲染引擎无法正确绘制,也就显示成了乱码。 
【解决办法】尽量还是使用Putty等伪终端软件,避免直接使用字符终端设备;如果实在不能避免,就要避免使用ASCII字符集以外的字符,好好学习英文吧。

4 杜绝乱码的最佳实践

所有编码统统设置为utf-8。这样既能够识别人类所有语言,又避免了各种编码之间转换的性能损失。

4.1 VIM设置

set encoding=utf-8
set termencoding=utf-8
set fileencodings=utf-8,gbk,latin1

如果无特殊要求和限制,磁盘文件也以UTF-8方式存储。

set fileencoding=utf-8

linux 文件编码问题的更多相关文章

  1. (转)剖析Linux文件编码的查看及修改

    Linux文件编码的查看和修改都有不止一种做法,如果你需要在Linux中操作windows下的文件,那么很可能会经常遇到文件编码转换的问题,如何进行这项工作,也应该是经常工作在双系统下的操作者的必须掌 ...

  2. linux文件编码

    linux下新建一个文件,或采用fopen新建,那么文件的编码是什么? 怎么查看文件编码格式: 查看文件编码file命令file ip.txt ip.txt: UTF-8 Unicode text, ...

  3. windows linux 文件编码转换

    查看文件编码在Linux中查看文件编码可以通过以下几种方式:1.在Vim中可以直接查看文件编码:set fileencoding即可显示文件编码格式.如果你只是想查看其它编码格式的文件或者想解决用Vi ...

  4. Linux 文件编码问题及iconv命令

    iconv命令是运行于linux/unix平台的文件编码装换工具.当我们在linux/unix系统shell查看文本文件时,常常会发现文件的中文是乱码的,这是由于文本文件的编码与当前操作系统设置的编码 ...

  5. Linux查看文件编码格式及文件编码转换

    Linux查看文件编码格式及文件编码转换   如果你需要在Linux 中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而L ...

  6. Linux中查看文件编码

    在Linux中查看文件编码可以通过以下几种方式:1.在Vim中可以直接查看文件编码:set fileencoding即可显示文件编码格式.如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱 ...

  7. shell 脚本文件Windows传到Linux后编码问题

    shell 脚本文件Windows传到Linux后编码问题 下面这个标红的位置出现,是由于脚本从Windows机器上直接传到linux文件格式不对导致的. cat -v a.sh help^M exi ...

  8. linux下文件编码的查看与修改

    在Linux中查看文件编码可以通过vim编辑器来查看,在vim命令模式下输入如下命令即可: :set fileencoding //在vim中查看文件编码 如果你只是想查看其它编码格式的文件或者想解决 ...

  9. linux下查看文件编码及修改编码

    http://blog.csdn.net/jnbbwyth/article/details/6991425 查看文件编码在Linux中查看文件编码可以通过以下几种方式:1.在Vim中可以直接查看文件编 ...

随机推荐

  1. (转)android系统架构及源码目录结构

    转自:http://blog.csdn.net/finewind/article/details/46324507 1. Android系统架构: android系统架构采用了分层架构的思想,如下图所 ...

  2. C语言中的数组问题

    数组默认最后一位是 结束符 占一位, 假如是7个字节大小的数组 实际输入为6个字节,最后一个字节为'\0' 这样写 char password_set[7]={"123456"}; ...

  3. Publish/Subscribe Model——Notification chain——观察者模式

    内核中用的很多,整理时间子系统的时候又遇到了notification mechanism,因此做次记录: 参考:1.http://msdn.microsoft.com/en-us/library/ff ...

  4. 在Eclipse中查看Javadoc文档

    当我们需要查看JDK中类的API介绍时,通常采用的方式是直接查看离线文档或者某些网站提供的在线文档.如下图: 而本文档最终达到的效果是,不需要切换出eclipse,直接在eclipse中查看JDK的J ...

  5. Asp.net mvc怎么在razor里写js代码

    我试图在Razor里写JS代码,但是不行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3 ...

  6. apt 之 最强技能:【欺骗】,文雅点【偷梁换柱】!

    apt这种软件包管理系统,有个最大特点是:只照本宣科,而不管实际情况. 所以,我们用户就可以利用这一点,来欺骗它,达到我们的目的. ------------------------------好了,现 ...

  7. ambari hdp 集成 impala

    1.下载ambari-impala-service VERSION=`hdp-select status hadoop-client | sed 's/hadoop-client - \([0-9]\ ...

  8. bashrc profile的区别

    bashrc与profile的区别 bashrc和profile的差异在于:1. bashrc是在系统启动后就会自动运行.2. profile是在用户登录后才会运行.3. 进行设置后,可运用sourc ...

  9. [转]油猴Tampermonkey-让百度云下载飞起来

    1. 简介 Tampermonkey,油猴脚本是一款免费的浏览器扩展程序. 我们这里用于Chrome浏览器,目的是为了让百度云里面的文件以满速下载,VIP还得出钱呢. 2. 安装 安装Lantern蓝 ...

  10. mySql的desc与explain分析性能(主要分析索引)

    desc select * from A where id =‘110’; 查询结果的含义请参考:http://www.2cto.com/database/201209/156466.html