zoukankan      html  css  js  c++  java
  • 27程序集资源

    程序集资源可以看作是Dictionary<string,byte[]>的字节数组。可以将资源直接嵌入到程序集中;也可以将资源单独嵌入到一个程序集,然后由主程序集引用包含资源的程序集,包含资源的程序集也叫卫星程序集(Satellite Assembly)。一个运用场景是:当开发多语言版本应用程序时,把不同的语言包作为资源签入到各个卫星程序集中,供主程序集调用。

     

      通过VS可视化界面把资源嵌入到程序集,并浏览资源文件

    在VS下创建Images/1.jpg→右键1.jpg→属性→生成操作的值设置为"签入的资源"
    1

     

    通过Assembly的实例方法获取资源名称:

            static void Main(string[] args)
            {
                ShowResources();
                Console.ReadKey();
            }
     
            private static void ShowResources()
            {
                Assembly asm = Assembly.GetExecutingAssembly();
                string[] nameArray = asm.GetManifestResourceNames();
                foreach (string name in nameArray)
                {
                    Console.WriteLine(name);
                    using (Stream s = asm.GetManifestResourceStream(name))
                    {
                        Console.WriteLine("资源字节流的长度为:{0}",s.Length);
                    }
                }
            }

    结果:
    2

     

      通过C#编译器将资源嵌入到程序集,并浏览资源文件

    →把上面的Program.cs和1.jpg复制到F:m文件夹下。

    →打开"开发人员命令提示",输入:
    3

    结果:
    4

     

      通过在VS中创建.resx文件把资源嵌入到程序集

    →在VS项目下创建Resource1.resx文件,输入资源:
    10

    →把Resource1.resx和2.jpg一同复制到F:m文件夹中。  

    →使用resgen.exe工具,根据Resource1.resx生成后缀为.resources的资源文件(这个才是真正的资源文件,包含了二进制内容)
    5
    生成完后,在F:m文件夹中多了Resource1.resources资源文件

    →写一段主程序Program1.cs来浏览Resource1.resources资源文件

    using System;
    using System.Reflection;
    using System.IO;
     
    class Program1{
        static void Main(string[] args){
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] nameArray = asm.GetManifestResourceNames();
            foreach(string name in nameArray){
                Console.WriteLine(name);
                using(Stream s = asm.GetManifestResourceStream(name)){
                    StreamReader reader = new StreamReader(s);
                    string text = reader.ReadToEnd();
                    if(text.Length > 1000) text = text.Substring(0,1000);
                    Console.WriteLine(text);
                    Console.ReadKey();
                }
            }
        }
    }
     

    →把Resource1.resources资源文件嵌入到程序集,生成Program1.exe

    6
    生成完后,在F:m文件夹中多了Program1.exe文件

    →运行Program1.exe

    7
    可见,Resource1.resources资源文件的内容的确是二进制的。

    →把可视化Resource1.resx文件签入到程序集,生成Program1.exe

    8
    生成完后,在F:m文件夹中Program1.exe文件进行了更新

    →再次运行Program1.exe

    9

    可见,在VS中创建的可视化Resource1.resx和通过resgen.exe工具生成的Resource1.resources是有本质区别的,前者是xml文件,后者的内容是二进制。

     

      通过反射获取后缀为.resources的资源文件信息

    →主程序中通过ResourceManager来获取资源信息

    using System;
    using System.Reflection;
    using System.IO;
    using System.Resources;
    using System.Drawing;
     
    class Program1{
        static void Main(string[] args){
            ResourceManager r = new ResourceManager("Resource1", Assembly.GetExecutingAssembly());
            string address = r.GetString("address");
            Console.WriteLine("address:" + address);
            Console.ReadKey();
        }
    }
     

    →输入命令

    11
    生成完后,在F:m文件夹中Program1.exe文件进行了更新

    →再次运行Program1.exe

    12

     

      把资源嵌入到独立程序集中,让主程序来调用

    →输入命令,把Resource1.resources资源文件签入到res.dll程序集中

    13
    生成完后,在F:m文件夹中多了res.dll程序集文件

    →主程序中引用res.dll程序集

    using System;
    using System.Reflection;
    using System.IO;
    using System.Resources;
    using System.Drawing;
     
    class Program1{
        static void Main(string[] args){
            Assembly asm = Assembly.Load("res");
            ResourceManager r = new ResourceManager("Resource1", asm);
            string address = r.GetString("address");
            Console.WriteLine("address:" + address);
            Console.ReadKey();
        }
    }
     

    →输入命令

    14

    →再次运行Program1.exe

    12

     

      开发多语言版本应用程序

    →创建Resource.en.resx文件

    15

    →重新生成项目,在bindebug下多了en文件夹

    16

    →主程序区域性设置为en

                Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
                ResourceManager r = new ResourceManager("ConsoleApplication25.Resource",Assembly.GetExecutingAssembly());
                string address = r.GetString("address");
                Console.WriteLine("address:" + address);
                Console.ReadKey();

    结果:
    17

    →把设置区域性en注释掉,默认是中文

                ResourceManager r = new ResourceManager("ConsoleApplication25.Resource",Assembly.GetExecutingAssembly());
                string address = r.GetString("address");
                Console.WriteLine("address:" + address);
                Console.ReadKey();

    结果:
    12

     

      总结

    为什么需要把资源嵌入到程序集?
    ● 当设计多语言版本的应用程序,可以根据各个国家语言生成对应的资源文件。
    ● 当资源文件比较大时,把资源文件嵌入到卫星程序集,可以大大减少主程序集的负担。

     

    把资源嵌入到程序集或卫星程序集有几种方式:
    1、通过资源文件属性设置
    2、通过C#编译器
    3、通过.resx资源文件    

     

    VS可视化界面中的.resx资源文件和最终生成的.resources资源文件是有区别的:
    前者的内容是xml文件。
    后者的内容是二进制文件。

     

    参考资料:
    《.NET之美》--张子阳,感谢写了这么好的书!

  • 相关阅读:
    高精度模板 支持各种运算 c++
    404 页面不存在
    多柱汉诺塔问题“通解”——c++
    高精度gcd
    404 页面不存在
    如何开启音乐二倍速?不下载其他软件【win10】
    如何随时学习数学
    洛谷P1004 方格取数
    Title
    Title
  • 原文地址:https://www.cnblogs.com/darrenji/p/3651144.html
Copyright © 2011-2022 走看看