转:C#资源文件

来源:互联网 发布:ubuntu ssd 4k对齐 编辑:程序博客网 时间:2024/06/10 06:24

资源文件概念

   在 .NET 中准备World-Ready程序时需要三步:Globalization 、Localizability 和Localization。第三步的Localization就是使用资源文件最常见的地方。程序的逻辑界面需要与资源界面隔离,而资源界面就是我们所说的资源文件。顾名思义,一个资源文件中当然全是资源,这里所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。
   资源文件可以有多种语言版本。如,一个 Strings.resources 文件可以有英语版、简体中文版、繁体中文版等。ResourceManager可以自动根据文件名来确认调用哪个版本。不同的版本只要在文件名中添入区域语言就可以了。比如:
   Strings.resources -------------- 默认版
   Strings.en-US.resources -------- 美国英语版
   Strings.zh-CHS.resources ------- 简体中文版
   Strings.zh-CHT.resources ------- 繁体中文版
   所谓的默认版就是当找不到适当的资源版本时用的资源。默认文件应当被嵌入到主 Assembly 中,这样就不会发生找不到资源的错误。在VS.NET 中将一个文件的属性设为 Embedded Resource , 就可以使资源被嵌入到主 Assembly中。
资源文件类型
    System.Resources名字空间支持三种资源文件:
(1).txt 文件,只能有字符串资源。因为不能被嵌入到 Assembly中,所以很容易暴露,被客户修改。最大缺点是仅支持字符串资源,所以不推荐使用。
(2).resx 文件,由 XML 组成,可以加入任何资源,包括二进制。同样不能被嵌入到 Assembly 中。在System.Resources 名字空间中有专用读写的类。VS.NET 创建这种文件然后将其转成 .resources文件并根据设置将其嵌入到 Assembly 中。
(3).resources 文件,PE 格式,可以加入任何资源。唯一可以被嵌入到 Assembly 的文件,在System.Resources 名字空间中有专用读写的类。
资源文件调用方法
  ResourceManager 可以根据不同的 UICulture设置返回不同的本地资源,我们只需知道调用资源用到它就可以了。接下来让我们看看如何调用每一种:
(1).txt 文件:不可以直接调用,得先将其转换成 .resources 文件才能使用。
(2).resx 文件:可以用 ResXResourceReader来做读取,但是这种方法不直观,不推荐直接调用 .resx 文件。正确的方法是将其转换成 .resources 文件,然后用ResourceManager 作读取工作。注意如果是在 VS.NET 中添加的 .resx 文件,那么它们自动被设为Embedded Resource,转成 .resources 文件后被嵌入到 Assembly中。
(3).resources 文件分成两种情况:
    1、被嵌入或编译成Satellite Assembly:使用ResourceManager来获得在 Assembly 中的资源。
  2、单独文件,没被编译或嵌入到Assembly:使用ResourceManager.CreateFileBasedResourceManager来获得资源集(ResourceSet)。
(4)特殊情况:当直接嵌入一资源时,也就是说,不通过一个资源文件而直接将一资源嵌入到 Assembly 中。这可以在 VS.NET中通过设置一文件的 Build 属性为 Embedded Resource 实现。在这种情况下 ResourceManager就没有用了,因为它只能获取 .resources 资源文件。那么如何调用这类的资源呢?不难,我们需要利用一些 Reflection中的特征。别怕,不是让你再学 Reflection,其实我们只要了解一些 System.Reflection.Assembly这个类中的一些函数就可以了。有三个相关函数,不过我们只需要 Assembly.GetManifestResourceStream这个函数。这个函数将一嵌入到 Assembly 中的资源以 stream 的方式返回,而我们可以将这个 stream 转成在 .NET中可用的对象。比如,如果嵌入资源是一图片,那么我们可以利用 New Bitmap(Stream) 这个构造方法获得这个图片资源的Bitmap 对象。

在新建的Windows项目中,一般自动生成两个资源文件:Form1.resx和Resources.resx。其中,Form1.resx在项目的根文件夹下,Resources.resx在Properties子文件夹下。这两个资源文件的使用方法是不一样的,因为对Form1.resx的访问需要构造Syste.Resources.ResourceManager对象,而访问Resources.resx里的资源可以直接使用Properties.Resources.resName(resName是你添加的资源的名称)。

访问Form1.resx

ResourceManager rm = new ResourceManager(typeof(Form1));

//创建ResourceManager对象 string stringResource = rm.GetString("resName");

// 根据资源的名称获取字符串资源

Image imageResource = (Image)rm.GetObject("resName");//根据资源名称获取资源,并转型 在Form1.Designer.cs窗体设计器生成的代码中,可以看到这样的代码: //只有向窗体上添加图标、图像等资源后,才会自动生成下面的代码。 ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1)); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 从代码可以看出,c#将窗体的图标文件作为资源进行保存了起来,然后利用ComponentResourceManager来获取这些资源。它和ResourceManager用法一样,System.ComponentModel.ComponentResourceManager继承自Syste.Resources.ResourceManager。访问Resources.resx Resources.resx文件位于Properties子文件夹下,在此文件夹中还存在一个Resources.Designer.cs文件,该文件中的代码都是由设计器自动生成的:namespace RootNameSpace.Properties { ...... internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; //返回此类使用的缓存 ResourceManager 实例。 internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RootNameSpace.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } //添加的资源将以属性的形式返回 internal static System.Drawing.Bitmap resName { get { object obj = ResourceManager.GetObject("resName", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } ...... }} 可以看出,设计器自动为我们包装好了这些资源,在默认的RootNameSpace命名空间(也即你的项目所在的命名空间)下生成 RootNameSpace.Properties子空间,并自动产生Resources类。所以,我们可以方便的以属性的形式来获取这些资源,Propperties.Resources.resName;也可以属性的形式获得ResourceManager来获取资源,Properties.Resources.ResourceManager.GetObject("resName")。 不仅在Properties文件夹下可以建立资源文件,也可以在任何地方创建资源文件。在建立名称为MyResource资源文件的同时,设计器会自动生成两个文件:MyResource.resx和MyResource.Designer.cs。其中后一个文件就包装了设计器自动生成的代码,以方便对资源文件的访问。