关于资源文件的相关操做。
//1.比较常见的有获取资源文件对应的文件流,而后转换到相对应的文件
//比较典型的作法是经过代码程序集加载指定资源
//以下经过Assembly的静态方法GetExecutingAssembly()获得程序集
//还有不少方式能够获得代码程序集
System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
Stream manifestResourceStream = null;
manifestResourceStream = asm.GetManifestResourceStream("MyLibrary." + filename);
return manifestResourceStream;
//获得该文件流,这里也能够是字符流。
//若是咱们资源文件对应的该清单是一个图片文件
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(manifestResourceStream, true);
//若是咱们的资源文件是光标文件
Cursor cursor = new Cursor(manifestResourceStream);
//图标
Icon icon = new Icon(manifestResourceStream);
//字符串
System.IO.StreamReader sr = new System.IO.StreamReader(manifestResourceStream);
string str = sr.ReadLine();
//2.另一种写法,主要是经过ResourceManager类的GetObject()方法
//也能够经过GetStream()获得流后执行操做.
System.Resources.ResourceManager manager =
new System.Resources.ResourceManager("资源名称", Assembly.GetExecutingAssembly());
Object target = manager.GetObject("资源文件名");//获取到指定的资源的值
//在这里对应咱们加入到资源文件的清单,
//转换回我没的目标值,可能会产生一个拆箱的过程
//若是咱们资源文件对应的该清单是一个图片文件System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)target;
//若是咱们的资源文件是光标文件
Cursor cursor = (Cursor)target;
//图标
Icon icon = (Icon)target;
//字符串
string str = target.ToString();//或者manager
manager.GetString("资源文件名");
//经过以上两种操做,就能够从资源文件中进行一个指定资源的加载了。
//前提是你的资源清单理存在该资源哦。
//推荐使用第种方法,这种方法也是MS Resx里对资源文件的操做方法。
//如今咱们已经能够读取资源文件了,如今开始写资源文件的操做。
//3.固然,你能够直接经过设计界面来添加一个资源文件,
//切记将生成操做改成“嵌入的资源”,Embed
System.Resources.ResourceWriter writer =
new System.Resources.ResourceWriter("dongpad.com.resources");
writer.AddResource("bitmap", Image.FromFile(@"dongpad.bitmap"));
writer.AddResource("cursor", Image.FromFile(@"dongpad.cursor"));
writer.AddResource("ico", Image.FromFile(@"dongpad.ico"));
writer.AddResource("str", Image.FromFile(@"dongpad.str"));
//在这里资源的名称记得要惟一。
writer.Generate();
writer.Close();
//下次給你们总结一下关于C#开发中经常使用的一些重写。但愿你们支持!
--参考文献--------------------------------------------------------------------------
什么是资源文件
在 .NET 中准备 World-Ready 程序时须要三步,Globalization,Localizability 和 Localization。在这第三步的 Localization 中就是使用资源文件最多见的地方。(本文不讨论 World-Ready 程序,或许之后在另外一篇文章中)由于程序的逻辑界面须要与资源界面隔离,而资源界面就是咱们所说的资源文件。顾名思义,一个资源文件中固然全是资源,不过,什么是资源?这里所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。注意一个资源文件能够有多种语言版本,举例,一个 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 名字空间支持三种资源文件:
.txt 文件,只能有字符串资源。由于不能被嵌入到 Assembly 中,因此很容易暴露,被客户修改。最大缺点是仅支持字符串资源,因此不推荐使用。
.resx 文件,由 XML 组成,能够加入任何资源,包括二进制。一样不能被嵌入到 Assembly 中。在 System.Resources 名字空间中有专用读写的类。VS.NET 建立这种文件而后将其转成 .resources 文件并根据设置将其嵌入到 Assembly 中。
.resources 文件,PE 格式,能够加入任何资源。惟一能够被嵌入到 Assembly 的文件,在 System.Resources 名字空间中有专用读写的类。
调用资源文件的几种方法
ResourceManager 能够根据不一样的 UICulture 设置返回不一样的本地资源(这与 World-Ready 程序有关,在此不讨论),咱们只需知道调用资源用到它就能够了。接下来让咱们看看如何调用每一种:
.txt 文件:
不能够直接调用,得先将其转换成 .resources 文件才能使用。(关于如何转换请看"推荐工具")
.resx 文件:
能够用 ResXResourceReader 来作读取,可是这种方法不直观,不推荐直接调用 .resx 文件。正确的方法是将其转换成 .resources 文件,而后用 ResourceManager 做读取工做。注意若是是在 VS.NET 中添加的 .resx 文件,那么它们自动被设为 Embedded Resource,转成 .resources 文件后被嵌入到 Assembly 中。
.resources 文件:
分红两种状况:
被嵌入或编译成 Satellite Assembly:
用 ResourceManager 的各类 constructor 来得到在 Assembly 中的资源。
单独文件,没被编译或嵌入到 Assembly 中:
能够用 ResourceManager.CreateFileBasedResourceManager 来得到资源集(ResourceSet),就是全部的资源。
特殊状况:
还有一种特殊状况,那就是当你直接嵌入一资源时,也就是说,不经过一个资源文件而直接将一资源嵌入到 Assembly 中。这能够在 VS.NET 中经过设置一文件的 Build 属性为 Embedded Resource 实现。在这种状况下 ResourceManager 就没有用了,由于它只能获取 .resources 资源文件(在或不在 Assembly 中)。那么如何调用这类的资源呢?不难,咱们须要利用一些 Reflection 中的特征。别怕,不是让你再学 Reflection,其实咱们只要了解一些 System.Reflection.Assembly 这个类中的一些函数就能够了。有三个相关函数,不过咱们只须要 Assembly.GetManifestResourceStream 这个函数。这个函数将一嵌入到 Assembly 中的资源以 stream 的方式返回,而咱们能够将这个 stream 转成在 .NET 中可用的对象。好比,若是嵌入资源是一图片,那么咱们能够利用 New Bitmap(Stream) 这个 Bitmap 的 constructor 得到这个图片资源的 Bitmap 对象。
注:在这里仅介绍怎样得到不一样的资源的方法,关于怎样用各个类与函数请参看有关文档。
如何准确的定义资源文件的逻辑位置
我想这是许多人最关注的一段了!在这里做者将解说如何正确的填写 ResouceManager(String, Assembly) 这个 constructor,还有如何正确的填写 Assembly.GetManifestResourceStream(String),由于它们两个的原理是相同的。看过了上面的描述,到了这里就简单多了。这里主要讨论的是怎么填写那个 String。这个 String 就是资源的完整名,一个完整名由它的名字空间和文件名前部分(BaseName)组成。例如,若是默认名字空间(root namespace)是 DefaultNamespace,资源文件的名字是 Strings.en-US.resources,那么它的完整名就是 DefaultNamespace.Strings。这个很简单,不过怎样肯定名字空间呢?这就有些奇怪了,由于 C# 的编译器与 VB.NET 的编译器有些不一样。做者在这里分别给出两个编译器怎样给嵌入资源自动添加命名空间:
C#
它自动添加 default namespace(与 root namespace 相同),但也添加子文件夹的名字。例如,在 Subfolder 子文件夹下放的资源文件 Strings.en-US.resources,它的完整名是 default namespace + subfolder + base name = DefaultNamespace.Subfolder.Strings
VB.NET
在 VB.NET 中就很简单了,它自动给嵌入资源添加 root namespace。无论你在哪一个子文件夹中放置资源文件,资源文件的完整名永远是 root namespace + base name。
根据上面的描述,若是咱们使用 C#,用 VS.NET 在 NewFolder 这个子文件夹中添加了一个叫 Images.resources 的资源文件,那么咱们应该用如下代码获取这些资源,假设 default namespace 是 MyDefault:
ResourceManager res = new ResourceManager("MyDefault.NewFolder.Images", this.GetTy函数