多语言处理

在学习如何使用.NET资源文件以及如何开发World-Ready程序之前,我们先通过一个例子来看看为什么要使用资源文件,以及使用它的好处。

假设要在程序中根据当前的Culutre来设置Form的Title和Logo:

private void Form1_Load(object sender, System.EventArgs e)   {

CultureInfo ci = new CultureInfo(Thread.CurrentThread.CurrentUICulture.ToString());

switch (ci.ToString().ToLower()) {

case "zh-cn":  // 中文版本

this.Text=FormTitle_ZH_CN;

imgLogo.Image = new Bitmap(Application.StartupPath + "/Logo_ZH_CN.jpg");

break;

case "en-us":  // 英文版本

this.Text=FormTitle_EN_US;

imgLogo.Image = new Bitmap(Application.StartupPath + "/Logo_EN_US.jpg");

break;

default:   // 默认版本

this.Text=FormTitle_Neutral;

imgLogo.Image = new Bitmap(Application.StartupPath + "/Logo_Neutral.jpg");

break;

}

}

这段代码有两个问题:

首先,Logo文件是暴露给用户的,而且是以普通文件的格式存储的,这导致其他程序或是用户很容易修改这些文件;节省硬盘空间的用户还可能会选择删除它,这些都可能会导致应用程序出错。确保图片或任何其他文件和代码在一起的唯一的安全方式是将它作为资源文件嵌入在程序集中并加载。

其次,这是一个World-Ready程序,如果需要新加入一个新的Culture,你可能不得不更改你的源代码,加入新的case,然后重新编译来适应新的Culture的需要,这对一个World-Ready程序来说是不现实的。开发World-Ready程序很重要的一点就是要保证程序的逻辑界面和资源界面的隔离。任何时候加入一个新的Culture资源,我们都不应该重新编译源程序,相反,我们只需要把新的资源文件准备好,然后发布给用户并部署在合适的目录下就可以了。应用程序应该能够根据不同的Culture来自动寻找合适的资源。

本文的目的就是通过实例来帮助读者了解什么是Resources,以及如何使用Resources来消除上面所提到的两个问题。

全文分为四部分:

第一部分是一些和资源相关的概念。

第二部分是一个实例程序(ResourceGenerator),用来说明如何创建资源文件。

第三部分是另外一个实例程序(WorldAPP),用来说明如何在程序中使用资源文件

第四部分是关于资源文件的命名和部署。分别介绍.NET中资源文件的命名方式和如何在World-Ready程序中配置资源文件。

第一部分 概念

先来了解一些概念:

1.        什么是资源文件

顾名思义,资源文件当然包含的全是资源。不过,什么是资源?这里所谓的资源就是程序中可利用的任何数据,譬如:字符串、图片或任何二进制格式的数据。一个资源文件可以有多种语言文化版本,比如,一个Culture.resources 文件可以有英语版、简体中文版日文版等。ResourceManager可以自动根据Culture和资源文件名来确认调用哪个版本。只不过不同的资源版本需要在文件名中加入语言文化信息(.resource文件有一套严格的命名规范,参考第四部分:资源文件的命名和部署)。

2.        资源文件的类型

System.Resources名称空间支持三种类型的资源:

.txt文件,只能有字符串资源。因为不能被嵌入到Assembly中,所以很容易暴露,被其他程序或用户修改。最大缺点是仅支持字符串资源,不推荐使用。

.resx文件,由XML组成,可以加入任何资源,包括二进制格式的。同样不能被嵌入到Assembly中。在System.Resources 名称空间中有专用读写的类。VS.NET中创建的这种文件也是将其转成.resources 文件然后根据设置将其嵌入到Assembly中。

.resources文件,PE格式,可以加入任何资源。是唯一可以被嵌入到Assembly的文件,在System.Resources名称空间中有专用读写的类(ResourceManager)。

3.        调用资源文件的几种方法

ResourceManager可以根据不同的UICulture设置返回不同的本地资源,不同Culture的资源文件有一套严格的命名规则,只有按照这个规则命名,CRL才可以根据Culture找到这个本地资源。PS:因为这个很重要,所以才一再出现J。参考第四部分:资源文件的命名和部署)

.txt 文件:

不可以直接调用,得先将其转换成 .resources 文件才能使用。

.resx 文件:

可以用ResXResourceReader来读取,但是这种方法不直观也不安全,不推荐直接调用.resx文件。正确的方法是将其转换成.resources文件,然后用ResourceManager读取。注意,如果是在VS.NET中添加的.resx文件,那么它们自动被设为 Embedded Resource,然后被转成.resources文件后嵌入到Assembly中。

.resources 文件:

分成两种情况:

·         被嵌入或编译成卫星程序集(Satellite Assembly):

用ResourceManager的各种constructor来获得在Assembly中的资源。

·         单独文件,没有被编译或嵌入到Assembly中:

可以用ResourceManager.CreateFileBasedResourceManager来获得资源集(ResourceSet),就是所有的资源。

特殊情况:

还有一种特殊情况,那就是当你直接嵌入一资源时,也就是说,不通过一个资源文件(.resources)而直接将一资源(Object)嵌入到 Assembly 中。这可以通过AL.exe(Assembly Linker)的参数/embed:<object>把资源嵌入在Assembly中。在这种情况下ResourceManager就没有用了,因为它只能获取.resources资源文件(在或不在Assembly中)。

调用这类直接嵌入在Assembly中的资源,我们就需要利用Reflection的一些特性来完成。在System.Reflection.Assembly类中有一些相关函数可以帮助我们拿到这些资源。通过Assembly.GetManifestResourceNames可以拿到所有的资源的名字,然后我们就可以通过Assembly.GetManifestResourceStream(<object_name>)这个函数拿到对应的资源并以stream的方式返回,然后我们可以将这个stream转成在.NET中可用的对象。比如,如果嵌入资源是一图片,那么我们可以利用New Bitmap(Stream)的constructor获得这个图片资源的Bitmap对象。

第二部分 创建资源文件

创建资源文件有两种方式,一种是使用.NET SDK自带的resgen工具来创建,另外一种是自己写code来创建。分别来介绍:

1.        Resgen:

这个工具是.NET自带的,它可以把.txt,.resX,转换为.resources文件。.resources文件是以一种以键-值方式对应存储的XML格式文件,每一个键<data>对应一个值<value>,这个<value>可以是任何的二进制格式。如果是格式为(键=值)对应得.txt文件,resgen会自动生成键-值对应的XML文件。但是resgen有一个局限性,它不能直接嵌入其他格式的文件,比如你就不能把.bmp以键-值得方式对应起来,因为你首先不能很容易得把.bmp以(键=值)对应的格式储存在.txt文件中。所以resgen主要是针对txt文件使用。

一个例子:company1.txt文件内容为:

Title = Company1

Address = Company1 Address

Phone = 12345678

-----------------------------------------------

时间: 2024-08-01 10:45:39

多语言处理的相关文章

使用R语言计算均值,方差等

R语言对于数值计算很方便,最近用到了计算方差,标准差的功能,特记录. 数据准备 height <- c(6.00, 5.92, 5.58, 5.92) 1 计算均值 mean(height) [1] 5.855 2 计算中位数 median(height) [1] 5.92 3 计算标准差 sd(height) [1] 0.1871719 4 计算方差 var(height) [1] 0.03503333 5 计算两个变量之间的相关系数 cor(height,log(height)) [1] 0

GCC在C语言中内嵌汇编 asm __volatile__ 【转】

转自:http://blog.csdn.net/pbymw8iwm/article/details/8227839 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会自动插入代码完成必要的操作. 1.简单的内嵌汇编 例: __asm__ __volatile__("hlt"); "__asm__"表示后面的

C语言轻松高效学习方法之:多种方法实现

多种方法实现同一个功能,可以调动你学的所有知识去做,有助于你学的融会贯通. 下面举例来看: 实现功能:求一个整数的位数: 实现语言:C语言: 开发环境:Visual Studio 2017 如:3215是4位数 实现原理: 3215/10 = 321 ----1位数 321/10 = 32 ----又是1位数 32/10 = 3 ----又是1位数 3/10 = 0 ----又是1位数 共4位数,且终止计算条件是/10结果为0的时候: 根据这个原理,先写一个最笨的原始方法: 效果: 这种实现方案

轻松学习C语言编程的秘诀:总结+灵感

目前在准备一套C语言的学习教程,所以我这里就以C语言编程的学习来讲.注意,讲的是"轻松学习",那种不注重方法,拼命玩命的方式也有其效果,但不是我提倡的.我讲究的是在方式方法对头.适合你.减轻你学习负担和心里压力的前提下,才适当的抓紧时间. 因此,探索一种很好的学习方法就是我所研究的主要内容. 众所周知,学习C语言并非易事,要学好它更是难上加难.这和你期末考试背会几个题目的答案考上满分没多大关系,也就是说你考试满分也说明不了你学好.学精通了C语言.那么怎么才算学精通C语言?闭着眼睛对自己

详解go语言的array和slice 【二】

上一篇  详解go语言的array和slice [一]已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变.这一篇里我会讲解到如何避免这些问题,以及迭代.和做为方法参数方面的知识点. slice的长度和容量设置为同一个值 如果在创建新的slice时我们把

自动生成小学四则运算题目(C语言)

这个简易四则运算是我在百度上找的博主叫53余雅诗的一篇c语言代码,网址为http://www.cnblogs.com/ys1101/p/4368103.html,功能是可以选择加减乘除进行简易的四则运算,判断对错.我在VS2017上编译没有bug,因为功能只有整数运算,所以我在此基础上加了真分数的四则运算以及统计得分等,最后成功运行程序.我把我的源代码放在github上,地址为https://github.com/xiaofancheng/helloworld.

PAT 1009 说反话 C语言

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格. 输出格式:每个测试用例的输出占一行,输出倒序后的句子. 输入样例: Hello World Here I Come 输出样例: Come I Here World Hello 1 #include<stdio.h> 2 #

PAT 1006 换个格式输出 C语言

让我们用字母B来表示"百".字母S表示"十",用"12...n"来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数.例如234应该被输出为BBSSS1234,因为它有2个"百".3个"十".以及个位的4. 输入格式:每个测试输入包含1个测试用例,给出正整数n(<1000). 输出格式:每个测试用例的输出占一行,用规定的格式输出n. 输入样例1: 234 输出样例1: BBSSS1

Go语言 IDE之Gogland配置使用

Gogland 是 JetBrains 公司推出的 Go 语言集成开发环境.Gogland 同样基于 IntelliJ 平台开发,支持 JetBrains 的插件体系.目前正式版尚未发布.官方:https://www.jetbrains.com/go/.关于使用,即将开始咯! 一.安装Golang 1) 首先到https://golang.org/dl/选择适合你系统的安装包,(墙内:http://golangtc.com/download). 2)下载完成安装到指定目录即可.我这里是(D:\G

R语言快速上手入门

R语言快速上手入门 课程学习网址:http://www.xuetuwuyou.com/course/196 课程出自学途无忧网:http://www.xuetuwuyou.com 课程简介 本教程深入浅出地讲解如何使用R语言玩转数据.课程中涵盖R语言编程的方方面面,内容涉及R对象的类型.R的记号体系和环境系统.自定义函数.if else语句.for循环.S3类R的包系统以及调试工具等.本课程还通过示例演示如何进行向量化编程,从而对代码进行提速并尽可能地发挥R的潜能.本课程适合立志成为数据科学家的