一、文件简介

.po文件,.mo文件,.pot文件是由gettext程序生成或者使用的源代码和编译结果。
 
1、.pot文件 
是一种模板文件,其实质与.po文件一样,其中包含了从源代码中提取所有的翻译字符串的列表,主要提供给翻译人员使用。
从源码中扫描得到的翻译模版文件,原始语言取决于源码字符串中使用的自然语言,建议使用英文。纯文本格式;
 
2、.po文件 
根据 POT 文件建立的各种语言版本的待翻译文件,其中包含原始语言和被翻译的目标语言。纯文本格式;
(1)用程序msginit来分析pot文件,生成各语言对应的po文件,比如中文就是zh_CN.po,法语就是fr.po文件。 
(2)PO是Portable Object(可移植对象)的缩写形式,它是面向翻译人员的、提取于源代码的一种资源文件。 
(3).po文件可以用任何编辑器如poEdit,vi,Emacs,editplus打开,交给翻译人员来将其中的文字翻译成本国语言。
 在我们系统中,直接新建.po文件修改即可。在诊断模式下:/usr/share/locale/zh_CN/LC_MESSAGES路劲下存放了对应的mo.po文件。目前仅支持中英文!
 
3、.mo文件 
供最终软件实际使用的文件,使用 PO 编译而成。二进制格式。
(1)用msgfmt将.po文件编译成mo文件,这是一个二进制文件,不能直接编辑。 
(2)MO是Machine Object(机器对象)的缩写形式,它是面向计算机的、由.po文件通过GNU gettext工具包编译而成的二进制文件,应用程序通过读取.mo文件使自身的界面转换成用户使用的语言,如简体中文。 
(3)可以用工具如msgunfmt命令将.mo文件反编译为.po文件。 
 

gettext是一套工具集的名称。这套工具集包含 xgettext/msginit/msgfmt 等一套建立模版(POT)、创建PO文件和编译MO文件的工具。

gettext 包含的工具如下:

  • xgettext 从源码中生成POT模版或直接生成PO文件
  • msginit 基于POT文件生成待翻译的PO文件;
  • msgfmt 将PO文件编译成二进制的MO文件;
  • msgunfmt 顾名思义,将MO文件反编译成PO文件;
  • msgmerge 将POT模版文件与PO文件合并。用于在源码更新之后将新的待翻译内容更新到已经翻译的PO文件中;
  • msgcat 将多个PO文件合并在一起。
 
维护:
       维护po的翻译人员在每次得到从新的程序源代码产生的po时,都用msgmerge来根据旧的已翻 译过的po来先处理一下新的未翻译的po。
有的msgid前面一行有fuzzy的字样。这说明,第一这个po是被msgmerge处理过的;第二,已翻译的po里没有和这个msgid完全等同的 msgid,只有非常相似的。这种情况下,msgmerge仍然会用那个相似的msgid来翻译此msgid。不过会给这个msgid标记为fuzzy, 表示翻译人员仍然要翻译这 个msgid,并在翻译后去掉上面带fuzzy的这一行(翻译好后必须去掉,fuzyy。否则无法显示译文)。
在我们系统中,原本/usr/share/locale/zh_CN/LC_MESSAGES路劲下仅存放了对应的mo文件。为了便于扩展,修改src/locale/zh_CN下的Makefile使得生成的po文件也保存在该路径下。翻译人员可以取得该po文件进行对应的翻译。然后将该翻译过后的po文件(例如中日,中韩)存放在/usr/share/locale/路径下即可。最后在程序代码中根据当前语言环境在该目录下寻找指定的语言包进行翻译即可。比如zhonghan.po。由于存在预加载,我们翻译好的.po文件需要重新编译版本下载安装。
TIPS:假如想增加日文提示。需要在src/locale目录下仿照zh_CN再新建一个目录,Makefile的编写仿照zh_CN目录即可。然后在新建目录下添加翻译好的中日po文件。Makefile根据这个文件进行编译安装即可。同时也需要记得修改系统的查找mo文件函数。设备目前路径是usr/share/locale//zh_CN/LC_MESSAGES/msg.po,只需要仿照即可在locale目录下新增路径即可。
如图所示:传入的lang需要和页面进行交互讨论,目前系统仅支持中文,需要新定义新的语言字段。然后下面的查找判断再根据传入的新语言类型增加一个判断即可。若bindtextdomain为空代表在当前路径下默认绑定最先找到的mo文件。testdomain则解读指定的mo文件,若为空则默认读取最新读到的mo文件。故存在多个mo文件需要指定绑定的mo. 详情参考man bindytextdomain 3.
 
PO文件详解:
po文件都是由一对对的msgid和msgstr组成的。msgid就是原文。msgstr就是译文。

注:对于不可能出现的提示信息可以不写中文翻译。 

1.可以看到setlocale(LC_ALL, " ");设置语言环境,第二个参数如果为空代表读取当前语言环境locale。设置失败返回NULL。“”之间不能加空格。

2.接着就是bindtextdomain("msg", LANGUAGE_PATH),参考:man 3 bindtextdomain,功能是:设置包含 LC_MESSAGES 分类 (catalog) 的 locale 目录,程序的 .mo 文件就保存到其下的目录中。LC_MESSAGES 是 locale 的一个分类 (catalog),和其它的分类,如:LC_TIME、LC_CTYPE,是平级的概念。domainname、locale 目录、程序当前活动 locale,这三者会决定你需要将 .mo 放到 locale 目录的具体位置,因为当前locale可能是中文zh_CN,也可能是繁体中文zh_TW。最终存放路劲是: [locale 目录]/[活动 locale]/LC_MESSAGES/msg.mo。本设备存放路径则是usr/share/locale//zh_CN/LC_MESSAGES/msg.po
3.textdomain("msg");参考:man 3 bindtextdomain,功能是:设置后来使用 gettext() 时的 domain。示例中设置:textdomain("msg")。一般与上一步的domainname相同。若存在多个mo文件,上述函数进行多次绑定后,则该函数就特别指定当前需要绑定的mo文件。
4.gettext();参考:man 3 gettext, 功能是:根据环境读取mo文件中的 msgid还是msgstr,并返回适当的语言类型。
 
总结步骤:
一般的工作流程是这样的:
  1. 在源码中使用约定的语法来书写字符串,C语言默认是 gettext("hello, world")。在本文中,将使用 _("hello, world")
  2. 使用 xgettext 从源码中扫描出需要翻译的文本,建立 POT 文件;
  3. 使用 msginit 命令根据 POT 文件建立 PO 文件。或者直接在上一步也可以直接建立 PO 文件;
  4. 进行人工翻译(当然也可以进行机器翻译),翻译的结果保存在 PO 文件中;
  5. 使用 msgfmt 命令将 PO 文件编译成 MO 文件;
  6. 在程序中实现调用命令,本文中是 _ 函数,这个函数将读取并解析 MO 文件,根据调用的原始语言文本返回翻译之后的文本。
        
C语言简单实例:
1.新建1.c文件如下:

2.xgettext -a 1.c -o 1.pot生成pot文件。会提取出所有的字符串,如下:
3.根据.pot文件可以产生不同.po文件。
    export LANGUAGE=zh_CN设置当前语言环境为中文。
    msginit -l zh_CN.utf-8 -i 1.pot初始化1.pot文件,当前路径会生成zh_CN.po。
    进入zh_CN.po文件中增加对应字符串中文翻译即可。
4.msgfmt zh_CN.po -o zh_CN.mo根据po文件生成mo文件。
5.cp -f zh_CN.mo /usr/share/locale/zh_CN/LC_MESSAGES/test.mo。注意test.mo中的名称需要和代码中的domianname名称一致。
   复制mo文件到语言目录下。
 
gcc 1.c,然后./a.out即可看到屏幕打印出来的是:“你好,世界”。
若export LANGUAGE=en,即可看到屏幕打印出来的是:“hello, world”。
 
若添加其他语言也很简单,只需要对待一个中文一样,生成一个mo文件,并安装到系统中对应的目录然后根据系统语言环境变量来读取即可。切换不同语言就相当于修改locale.
 
 
 
 

关于操作系统中英文切换的.po和.mo介绍的更多相关文章

  1. QT in VS 多语言实现(中英文切换,每个步骤都有截图,只有UTF8才能让Qt语言家正确读取。先qApp->removeTranslator,然后installTranslator,每个类都要写上槽函数RetranslateUI)

    最近项目需要软件具有中英文双语切换功能,而QT又自带此功能,现将实现方式记录下来. 说到中英文切换,少不了要了解QT的内部编码方式.在此就不详述QT编码方式了,具体可参考 彻底弄懂Qt的编码.只需要记 ...

  2. erp中三大订单CO、PO、MO各是代表什么?

    ERP即 企业资源计划 (Enterprise Resource Planning),由美国 Gartner Group 公司于1990年提出. ERP系统是指建立在信息技术基础上,以系统化的管理思想 ...

  3. SpringMVC 国际化-中英文切换

    项目结构 1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http: ...

  4. ThinkPHP3.2中英文切换!

    小伙伴们好久不见!!!   最近公司项目版本升级,小梦已经忙成了狗,无暇顾及文章,今天抽时间写一篇助助兴!   用Thinkphp这个国产框架已经2年多了,现在有一个小功能:网站中英文切换功能,当然这 ...

  5. xadmin在Django 1.11中的使用及中英文切换

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com xadmin是一个强大的替代django admin的管理后台,github地址为:https://g ...

  6. 无法启动 Maya 集成的 qt designer 的解决方法和原因 以及 中英文切换

    无法启动 Maya 集成的 qt designer 的解决方法和原因 以及 中英文切换 前言: Maya 集成了 PySide,同时集成了qt designer,在 Maya 的安装目录下的 bin ...

  7. 关闭shift中英文切换 英文代码/中文注释随意切换着写。

    x 背景 写代码的时候总是意外的就切成中文了,特别是代码中大小写切换的这种情况... 例如:"public static TimeZone CurrentTime..."publi ...

  8. erp中三大订单CO、PO、MO

    ERP即 企业资源计划 (Enterprise Resource Planning),由美国 Gartner Group 公司于1990年提出. ERP系统是指建立在信息技术基础上,以系统化的管理思想 ...

  9. C#学习笔记-中英文切换(XML)

    这几天因为软件需要加英文版本,所以查了好久的资料找到了相关的信息,原资料参考:http://blog.csdn.net/softimite_zifeng 上网查的中英文切换大约有两种方式:1.动态加载 ...

随机推荐

  1. LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)

    题目标签:Linked List 题目给了我们一组 linked list,让我们把每对nodes 互换位置. 新键一个dummy node,然后遍历list,每次建立 s1 和 s2 记录两个点,然 ...

  2. DRF的请求响应组件

    目录 DRF的请求响应组件 请求模块(request) 概念 request源码简单分析 响应模块(response) 概念 使用方法 response源码简单分析: 解析模块(parse) 概念 使 ...

  3. 解决WIN8输入法的问题,Ctrl+空格,Ctrl+Shift,切换问题

    在WIN8中,我们曾经熟悉的的Ctrl+空格和Ctrl+Shift消失了,取而导致的是WIN+空格. 在这里先简单解释一下WIN8的输入法结构: 在WIN7以前的输入法中,输入法采用了平行目录的结构, ...

  4. maven javaProject打包发布成服务

    1,现在pom.xml中添加打包所需要的jar包. <plugins> <plugin> <groupId>org.apache.maven.plugins< ...

  5. 2019-3-16-win10-uwp-在-ItemsPanelTemplate-里面通过样式绑定-Orientation-显示方向

    title author date CreateTime categories win10 uwp 在 ItemsPanelTemplate 里面通过样式绑定 Orientation 显示方向 lin ...

  6. ionic js 加载动画 ionSpinner 提供了许多种旋转加载的动画图标。当你的界面加载时,你就可以呈现给用户相应的加载图标。 该图标采用的是SVG

    ionic 加载动画 ion-spinner ionSpinner 提供了许多种旋转加载的动画图标.当你的界面加载时,你就可以呈现给用户相应的加载图标. 该图标采用的是SVG. 用法 <ion- ...

  7. 引用数据类型 Scanner Random

    Scanner类 数据类型  变量名  =  new 数据类型(); 每种引用数据类型都有其功能,我们可以调用该类型实例的功能. 变量名.方法名(); Scanner类是引用数据类型的一种,我们可以使 ...

  8. 阿里云宣布 Serverless 容器服务 弹性容器实例 ECI 正式商业化

    摘要: 阿里云宣布弹性容器实例 ECI(Elastic Container Instance)正式商业化,ECI 是阿里云践行普惠的云计算理念,将 Serverless 和 Container 技术结 ...

  9. 剑指Offer-14:输入一个链表,输出该链表中倒数第k个结点。

    题目描述: 输入一个链表,输出该链表中倒数第k个结点.例如有一个链表有六个节点1,2,3,4,5,6.则它的倒数第二个节点为5 节点定义如下: public class ListNode { int ...

  10. 模拟求root——cf1067B

    注意最后一轮要单独求一下 且最后只能有一个root #include <bits/stdc++.h> using namespace std; #define MOD 1000000007 ...