日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Globalization Resources

發布時間:2023/11/27 生活经验 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Globalization Resources 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://blog.csdn.net/etmonitor/


.NET
系統學習----Globalization & Resources

l????????? 前言

l????????? 了解資源文件

l????????? 創建資源文件

l????????? 在程序中使用資源文件

l????????? 資源文件的命名和部署

l????????? 參考

前言:

在學習如何使用.NET資源文件以及如何開發World-Ready程序之前,我們先通過一個例子來看看為什么要使用資源文件,以及使用它的好處。

假設要在程序中根據當前的Culutre來設置FormTitleLogo

?????? 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.exeAssembly Linker)的參數/embed:<object>把資源嵌入在Assembly中。在這種情況下ResourceManager就沒有用了,因為它只能獲取.resources資源文件(在或不在Assembly中)。

調用這類直接嵌入在Assembly中的資源,我們就需要利用Reflection的一些特性來完成。在System.Reflection.Assembly類中有一些相關函數可以幫助我們拿到這些資源。通過Assembly.GetManifestResourceNames可以拿到所有的資源的名字,然后我們就可以通過Assembly.GetManifestResourceStream<object_name>)這個函數拿到對應的資源并以stream的方式返回,然后我們可以將這個stream轉成在.NET中可用的對象。比如,如果嵌入資源是一圖片,那么我們可以利用New BitmapStream)的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

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

Resgen company.txt <outputfilename>.resources

如果不指定<outputfilename>,默認會生成company1.resources。

然后就可以通過ResourceManager來使用了。

還可以再進一步,通過AL.exeresources文件變為一個assembly(使用assembly有很多好處(比如可以加入版本信息和Culture信息等)詳見(.NET系統學習----Assembly)。

Al /out:company1.dll /embed:company1.resources

通過設置ResourcesManager的不同的constructor就可以訪問Assembly中包含的.resources文件(下面的例子會講到)。

2.??????? 通過編程使用IResourcsWrite來生成資源文件

上面的方法的一個最大的缺點是不能很方便的嵌入其他格式的資源,因為把其他格式的資源變為鍵-值對應得txt文件并不是一件很容易的事。所以我們介紹另一種方法,通過編程,使用.NET提供的IResourcesWrite類來實現把任何資源嵌入到resources文件中。

ResourceGenerator就是用這種方式實現的。

程序的主界面:

?

用到的主要方法就是:

private void OnGenerateResource(object sender, System.EventArgs e)

{

IResourceWriter rw = new ResourceWriter(“C:/test.resources”);

?????? switch (sType)

?????? {

?????? ?????? case "system.string":

????????????? rw.AddResource(sKey,sValue);

????????????? break;

????????????? case "system.drawing.bitmap":

????????????? Bitmap bmp = new Bitmap(sValue);

????????????? rw.AddResource(sKey,bmp);

????????????? break;

????????????? case "system.drawing.image":

?????? ?????? Image img= new Bitmap(sValue);

????????????? rw.AddResource(sKey,img);

????????????? break;

}

}

根據資源的類型,如果不是string類型的,我們就把它分實例化為相應的stream,然后加入到resoruces中即可(string類型可以直接加入)。生成的就是.NET可以直接使用的.resources文件。但是這樣生成的資源CLR并不能根據不同的Culture自動識別。要想CRL自動識別并加載正確的資源文件,首先必須把.resources轉換為Assembly并根據嚴格的命名方式命名(參考第四部分:資源文件的命名和部署),并部署到正確的目錄下,然后CLR就可以根據不同的Culture來加載正確的資源。

第三部分 在程序中使用資源文件

WorldApp.cs是一個World-Ready的程序,它的邏輯界面和資源界面是分開的,可以實現邏輯界面只Bulid一次,運行時根據當前的Culture調用相應的Satellite Assembly(衛星資源程序集)來實現本地化。添加一個新的Culture資源不需要重新Build源程序,只需要把相應的資源程序集部署到合適的目錄就可以了。

下面說明WorldApp的實現方式:

程序主界面:

程序在啟動的時候會根據當前的CurrentUICulutre去加載相應的資源文件。

讀取資源文件的代碼為:

?????? private void SetCulture( CultureInfo ci )

?????? {

????????????? // Change current UI culture

????????????? Thread.CurrentThread.CurrentUICulture = ci;

????????????? // Load culture resources.

????????????? String AssemblyPath = Application.StartupPath + "//Culture.dll";

????????????? Assembly asm = Assembly.LoadFrom(AssemblyPath);

// ResoruceManager constructor will load different resources acording to the

// CurrentUICulture. which means, if CurrentUICulutre is "en-US", rm will load

// "Culture.en-US.resources" automaticly.

// When loaded, give the resource name only.

????????????? ResourceManager rm = new ResourceManager("Culture", asm);?????????????

????????????? // Set title, culture info and logo.

????????????? this.lblTitle.Text = rm.GetString("Title");

????????????? this.lblCulture.Text = rm.GetString("Culture");

????????????? this.lblLogo.Text = rm.GetString("LogoTitle");

????????????? this.imgLogo.Image=(Bitmap)rm.GetObject("Logo");

}

如果當前的UICulture改變,可以通過顯式調用SetCulture( CultureInfo ci )來加載相應的Culture資源。

現在如果我們有了一個新的Culture資源版本,我們只需要把它部署在對應的Culture目錄下,WorldApp.exe就可以自動加載,WorldApp.exe程序本身并不用做任何更改(不需要編譯)。

你可以通過上面制作的小工具ResoruceGenerator來生成對應不同Culture的資源,然后把生成的Assembly正確部署就可以了。WorldApp就又有了一個新的Culture版本。哈!!

第四部分 資源文件的命名和部署

這部分說明資源文件的部署方式和CLR是如何識別并加載不同的Culture資源的。

·???????? 資源文件的命名方式

假設我們的應用程序名為WorldApp.exe,默認的資源文件為culture.resources,根據這個資源文件生成的Assemblyculutre.dll(這個是默認版本的資源文件)。然后我們有了一個en-US Culture版本的資源文件,則en-US的資源文件得名稱必須為culture.en-US.resources,根據這個資源文件生成的en-US版本的Assembly必須命名為culture.resources.dll且必須加入Culture信息(把一個.resources生成一個Assemblyresgen /out:cluture.resources.dll /c:en-US /embedcluture.en-US.resources),生成的Assembly必須放在程序運行目錄下的en-US目錄下,這樣CLR才能自動找到。同樣,如果我們有了一個zh-CN版本的資源文件,則資源文件的名稱必須為culture.zh-CN.resources,生成的Assembly必須為culture.resources.dll,并放在zh-CN目錄下。

重要:因為生成的.resources文件本身并不包含Culture信息,它的Culture信息就體現在它的文件名上,所以.resources的命名必須加入Cluture信息(如果不加的話,生成的就是默認版本)。從.resources生成Assembly時,因為Assembly可以指定Culture信息(通過/c:<culture>來指定),所以Assembly的名稱中不需要加入Culture信息,但是Assembly的名字必須是:默認版本名+<.resources>.dll,就是:culture.[resources].dll。

·???????? 資源文件的部署方式

應用程序正確的部署方式(目錄結構)應該是:

<WorldApp>?????????????????????? ?????? (應用程序主目錄)

WorldApp.exe??????????????????????????? (主程序)

Culture.dll???? ?????? ????????????? (包含culture.resources資源文件)

????????????? <en-US>?????? ????????????? en-US資源目錄)

?????? ?????? Culture.resources.dll?? (包含culture.en-US.resources資源文件)

??????? ?????? <zh-CN>????????????? ?????? zh-CN資源目錄)

????????????? Culture.resources.dll?? (包含culture.zh-CN.resources資源文件)

?????? ?????? <new-Culture>??? ?????? net-Culture資源目錄)

????????????? Culture.resources.dll?? (包含cluture.new-Culture.resources

?????? ?????? ?????? <…>?????? ????????????????????

有了上面的部署,App.exe在運行時,會首先根當前ThreadCurrentUICuluture到對應的目錄去尋找資源文件,比如當前的CurrentUICulture=”en-US”,則en-US目錄下的Culture.resources.dll Assembly中的culture.en-US.resources會被加載。如果CLR遍歷整個目錄還沒有找到對應的資源文件,則默認的資源文件版本就被加載(MSDN中稱為Hub and Spoke model方式 詳見:ms-help://MS.MSDNQTR.2004APR.1033/cpguide/html/cpconPackagingDeployingResources.htm)。

·???????? CLR如何加載資源文件

重要:CLR在匹配資源文件的時候,不是按文件來匹配的,它是按照<data>字段一個key一個key的去匹配。舉個例子:

默認版本的Culture資源文件中包含四個keyTitle, Culture, LogoTitle,Logo。

中文版本的Culture資源文件中包含只有三個KeyTitle, Culture, Logo。(沒有LogoTitle

如果當前的Culturezh-CN”,則zh-CN版本的Title, Culture, Logo都會被加載,但是因為zh-CN版本沒有LogoTitle,所以CLR會自動加載和zh-CN文化最匹配的一個資源版本的LogoTitle。如果都沒有,最后才會去加載默認版本的資源文件。

這樣做有一個很大的好處:就是說并不是所有資源都必須要有對應Culture的版本,我們可以把共通的資源放在默認版本中,只把和特定Culture相關的資源隔離就可以了。

重要:關于Culture

Culture信息是由主標記(文化)和次標記(地域)兩部分組成的。舉個例子:

en-US???? (英語-美國)

en-GB???? (英語-英國)

en-AU???? (英語-澳大利亞)

主標記是en,表示Culture都是英語文化,次標記(地域)區分了它們分別是哪個地區的英語。

說這個有什么用呢?

因為CLR在尋找資源的時候是以一種回退的方式來尋找的,就是說,他會首先去尋找最批的那個資源文件,如果沒有,則會搜索文化層次結構,以查找最接近于請求的匹配資源文件,并把生成異常作為最后一種手段。比如CLR在尋找en-US資源的時候沒有找到,CLR不會立即就去用默認版本匹配,而是會首先搜索文化層次結構,以查找最接近于en-US的資源(可能是en-GB或別的),如果找到,運行時就使用這個資源,如果還找不到,則會繼續搜索下一層,最后才會用默認版本匹配(如果默認版本也沒有,則會拋出一個異常)。

參考資料:

l????????? Applied Microsoft .NET Framework Programming ---- Jeffrey Richter

l????????? MSND Library

總結

以上是生活随笔為你收集整理的Globalization Resources的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人自拍视频网站 | 久久最新精品 | 成人高清在线 | 国产福利视频一区 | 精品午夜福利在线观看 | 国产精品手机在线 | 国产精品自拍偷拍视频 | 嫩草视频91| 午夜天堂网| 欧美一区免费 | 另类激情 | 国产人妖ts重口系列网站观看 | 久久毛片视频 | 香蕉视频亚洲 | 一区二区在线免费视频 | 黄色小网站在线观看 | 欧美一区二区黄色 | 久草a视频| av激情影院 | 麻豆黄色一级片 | 黄色av观看 | 九九热国产视频 | 男人久久久 | 精品777| 久久怡红院| 亚洲综合视频在线观看 | 亚洲jizzjizz日本少妇 | 亚洲免费中文字幕 | 亚洲怡红院av| 黄瓜视频在线观看 | 91玉足脚交白嫩脚丫 | 被黑人猛躁10次高潮视频 | 国产精品久久久久久久 | 成人福利视频导航 | 色哟哟视频在线 | 久久久无码人妻精品一区 | 亚洲一区 中文字幕 | 日韩bbw| 国产探花一区二区 | 黄色香蕉软件 | 日本在线一区二区 | 国产欧美一区二区三区精华液好吗 | 日韩视频中文字幕在线观看 | 自拍偷拍亚洲天堂 | 51调教丨国产调教视频 | 国产精品久久久久久久成人午夜 | free性欧美hd另类 | 青青草视频免费播放 | 久久久久久99精品久久久 | 午夜免费在线 | 亚洲免费天堂 | 亚洲成人自拍偷拍 | 五月综合激情日本mⅴ | 久久人妖| 前任攻略在线观看免费完整版 | 中文字幕日韩一区二区 | 学生调教贱奴丨vk | 天堂在线中文在线 | 久久另类ts人妖一区二区 | 国产美女91呻吟求 | 日韩在线观看中文字幕 | 中国在线观看视频高清免费 | 欧美午夜性春猛交 | 久久久久性色av无码一区二区 | 日韩精品手机在线 | 精品蜜桃一区二区三区 | 少妇太爽了| 四虎永久在线精品免费一区二区 | 天堂中文字幕 | 在线亚洲欧美 | 国产视频久久久久久久 | 欧美日韩一区在线 | 色婷婷激情综合 | 国产免费91视频 | 超碰97免费在线 | 69人人| 日本r级电影在线观看 | 黄色美女av | 国产一级二级在线观看 | 中文字幕1页 | 色屋视频 | 另类激情 | 激情第四色 | 欧美亚洲一区二区三区四区 | 免费av不卡在线观看 | 日韩一区视频在线 | 最新中文字幕在线 | 91亚洲网站 | 国产视频不卡一区 | 欧美日韩亚洲免费 | 中出在线播放 | 亚洲影院在线播放 | 岛国精品在线 | 男人亚洲天堂 | 福利视频在线导航 | 成人综合区 | 97精品一区二区视频在线观看 | 欧美激情精品久久久久久免费 | 特大黑人娇小亚洲女mp4 |