Bagikan melalui


Kelas System.Resources.ResourceReader

Artikel ini menyediakan keterangan tambahan untuk dokumentasi referensi untuk API ini.

Penting

Metode panggilan dari kelas ini dengan data yang tidak tepercaya adalah risiko keamanan. Panggil metode dari kelas ini hanya dengan data tepercaya. Untuk informasi selengkapnya, lihat Memvalidasi Semua Input.

Kelas ini ResourceReader menyediakan implementasi IResourceReader standar antarmuka. ResourceReader Instans mewakili file .resources mandiri atau file .resources yang disematkan dalam rakitan. Ini digunakan untuk menghitung sumber daya dalam file .resources dan mengambil pasangan nama/nilainya. Ini berbeda dari ResourceManager kelas , yang digunakan untuk mengambil sumber daya bernama tertentu dari file .resources yang disematkan dalam rakitan. Kelas ResourceManager ini digunakan untuk mengambil sumber daya yang namanya diketahui sebelumnya, sedangkan ResourceReader kelas berguna untuk mengambil sumber daya yang jumlahnya atau nama yang tepat tidak diketahui pada waktu kompilasi. Misalnya, aplikasi dapat menggunakan file sumber daya untuk menyimpan informasi konfigurasi yang diatur ke dalam bagian dan item di bagian, di mana jumlah bagian atau item di bagian tidak diketahui sebelumnya. Sumber daya kemudian dapat diberi nama secara generik (seperti Section1, , Section1Item1Section1Item2, dan sebagainya) dan diambil dengan menggunakan ResourceReader objek.

Penting

Jenis ini mengimplementasikan IDisposable antarmuka. Setelah selesai menggunakan jenisnya, Anda harus membuangnya baik secara langsung maupun tidak langsung. Untuk membuang jenis secara langsung, panggil metodenya Dispose dalam try/catch blok. Untuk membuangnya secara tidak langsung, gunakan konstruksi bahasa seperti using (di C#) atau Using (di Visual Basic). Untuk informasi selengkapnya, lihat bagian "Menggunakan Objek yang Menerapkan IDisposable" dalam IDisposable dokumentasi antarmuka.

Membuat instans objek ResourceReader

File .resources adalah file biner yang telah dikompilasi dari file teks atau file XML .resx menurut Resgen.exe (Resource File Generator). Objek ResourceReader dapat mewakili file .resources mandiri atau file .resources yang telah disematkan dalam rakitan.

Untuk membuat ResourceReader instans objek yang membaca dari file .resources mandiri, gunakan ResourceReader konstruktor kelas dengan aliran input atau string yang berisi nama file .resources. Contoh berikut mengilustrasikan kedua pendekatan. Yang pertama membuat ResourceReader instans objek yang mewakili file .resources bernama Resources1.resources dengan menggunakan nama filenya. Yang kedua membuat ResourceReader instans objek yang mewakili file .resources bernama Resources2.resources dengan menggunakan aliran yang dibuat dari file.

// Instantiate a standalone .resources file from its filename.
var rr1 = new System.Resources.ResourceReader("Resources1.resources");

// Instantiate a standalone .resources file from a stream.
var fs = new System.IO.FileStream(@".\Resources2.resources",
                                  System.IO.FileMode.Open);
var rr2 = new System.Resources.ResourceReader(fs);
' Instantiate a standalone .resources file from its filename.
Dim rr1 As New System.Resources.ResourceReader("Resources1.resources")

' Instantiate a standalone .resources file from a stream.
Dim fs As New System.IO.FileStream(".\Resources2.resources",
                                   System.IO.FileMode.Open)
Dim rr2 As New System.Resources.ResourceReader(fs)

Untuk membuat ResourceReader objek yang mewakili file .resources yang disematkan, buat objek Assembly dari assembly tempat file .resources disematkan. Metodenya Assembly.GetManifestResourceStream mengembalikan Stream objek yang dapat diteruskan ke ResourceReader(Stream) konstruktor. Contoh berikut membuat instans ResourceReader objek yang mewakili file .resources yang disematkan.

System.Reflection.Assembly assem =
             System.Reflection.Assembly.LoadFrom(@".\MyLibrary.dll");
System.IO.Stream fs =
             assem.GetManifestResourceStream("MyCompany.LibraryResources.resources");
var rr = new System.Resources.ResourceReader(fs);
Dim assem As System.Reflection.Assembly = 
             System.Reflection.Assembly.LoadFrom(".\MyLibrary.dll") 
Dim fs As System.IO.Stream = 
             assem.GetManifestResourceStream("MyCompany.LibraryResources.resources")
Dim rr As New System.Resources.ResourceReader(fs)

Menghitung sumber daya objek ResourceReader

Untuk menghitung sumber daya dalam file .resources, Anda memanggil GetEnumerator metode , yang mengembalikan System.Collections.IDictionaryEnumerator objek. Anda memanggil IDictionaryEnumerator.MoveNext metode untuk berpindah dari satu sumber daya ke sumber daya berikutnya. Metode ini mengembalikan false ketika semua sumber daya dalam file .resources telah dijumlahkan.

Catatan

ResourceReader Meskipun kelas mengimplementasikan IEnumerable antarmuka dan IEnumerable.GetEnumerator metode , ResourceReader.GetEnumerator metode ini tidak memberikan IEnumerable.GetEnumerator implementasi. Sebagai gantinya ResourceReader.GetEnumerator , metode mengembalikan IDictionaryEnumerator objek antarmuka yang menyediakan akses ke setiap pasangan nama/nilai sumber daya.

Anda dapat mengambil sumber daya individual dalam koleksi dengan dua cara:

  • Anda dapat melakukan iterasi setiap sumber daya dalam System.Collections.IDictionaryEnumerator koleksi dan menggunakan System.Collections.IDictionaryEnumerator properti untuk mengambil nama dan nilai sumber daya. Kami merekomendasikan teknik ini ketika semua sumber daya memiliki jenis yang sama, atau Anda mengetahui jenis data setiap sumber daya.

  • Anda dapat mengambil nama setiap sumber daya saat melakukan iterasi System.Collections.IDictionaryEnumerator koleksi dan memanggil GetResourceData metode untuk mengambil data sumber daya. Kami merekomendasikan pendekatan ini ketika Anda tidak mengetahui jenis data setiap sumber daya atau jika pendekatan sebelumnya melemparkan pengecualian.

Mengambil sumber daya dengan menggunakan properti IDictionaryEnumerator

Metode pertama untuk menghitung sumber daya dalam file .resources melibatkan pengambilan langsung setiap pasangan nama/nilai sumber daya. Setelah Anda memanggil IDictionaryEnumerator.MoveNext metode untuk berpindah ke setiap sumber daya dalam koleksi, Anda dapat mengambil nama sumber daya dari IDictionaryEnumerator.Key properti dan data sumber daya dari IDictionaryEnumerator.Value properti .

Contoh berikut menunjukkan cara mengambil nama dan nilai setiap sumber daya dalam file .resources dengan menggunakan IDictionaryEnumerator.Key properti dan IDictionaryEnumerator.Value . Untuk menjalankan contoh, buat file teks berikut bernama ApplicationResources.txt untuk menentukan sumber daya string.

Title="Contact Information"
Label1="First Name:"
Label2="Middle Name:"
Label3="Last Name:"
Label4="SSN:"
Label5="Street Address:"
Label6="City:"
Label7="State:"
Label8="Zip Code:"
Label9="Home Phone:"
Label10="Business Phone:"
Label11="Mobile Phone:"
Label12="Other Phone:"
Label13="Fax:"
Label14="Email Address:"
Label15="Alternate Email Address:"

Anda kemudian dapat mengonversi file sumber daya teks menjadi file biner bernama ApplicationResources.resources dengan menggunakan perintah berikut:

resgen ApplicationResources.txt

Contoh berikut kemudian menggunakan ResourceReader kelas untuk menghitung setiap sumber daya dalam file .resources biner mandiri dan untuk menampilkan nama kunci dan nilai yang sesuai.

using System;
using System.Collections;
using System.Resources;

public class Example1
{
   public static void Run()
   {
      Console.WriteLine("Resources in ApplicationResources.resources:");
      ResourceReader res = new ResourceReader(@".\ApplicationResources.resources");
      IDictionaryEnumerator dict = res.GetEnumerator();
      while (dict.MoveNext())
         Console.WriteLine("   {0}: '{1}' (Type {2})", 
                           dict.Key, dict.Value, dict.Value.GetType().Name);
      res.Close();
   }
}
// The example displays the following output:
//       Resources in ApplicationResources.resources:
//          Label3: '"Last Name:"' (Type String)
//          Label2: '"Middle Name:"' (Type String)
//          Label1: '"First Name:"' (Type String)
//          Label7: '"State:"' (Type String)
//          Label6: '"City:"' (Type String)
//          Label5: '"Street Address:"' (Type String)
//          Label4: '"SSN:"' (Type String)
//          Label9: '"Home Phone:"' (Type String)
//          Label8: '"Zip Code:"' (Type String)
//          Title: '"Contact Information"' (Type String)
//          Label12: '"Other Phone:"' (Type String)
//          Label13: '"Fax:"' (Type String)
//          Label10: '"Business Phone:"' (Type String)
//          Label11: '"Mobile Phone:"' (Type String)
//          Label14: '"Email Address:"' (Type String)
//          Label15: '"Alternate Email Address:"' (Type String)
Imports System.Collections
Imports System.Resources

Module Example2
    Public Sub Main()
        Console.WriteLine("Resources in ApplicationResources.resources:")
        Dim res As New ResourceReader(".\ApplicationResources.resources")
        Dim dict As IDictionaryEnumerator = res.GetEnumerator()
        Do While dict.MoveNext()
            Console.WriteLine("   {0}: '{1}' (Type {2})", dict.Key, dict.Value, dict.Value.GetType().Name)
        Loop
        res.Close()
    End Sub
End Module
' The example displays output like the following:
'       Resources in ApplicationResources.resources:
'          Label3: '"Last Name:"' (Type String)
'          Label2: '"Middle Name:"' (Type String)
'          Label1: '"First Name:"' (Type String)
'          Label7: '"State:"' (Type String)
'          Label6: '"City:"' (Type String)
'          Label5: '"Street Address:"' (Type String)
'          Label4: '"SSN:"' (Type String)
'          Label9: '"Home Phone:"' (Type String)
'          Label8: '"Zip Code:"' (Type String)
'          Title: '"Contact Information"' (Type String)
'          Label12: '"Other Phone:"' (Type String)
'          Label13: '"Fax:"' (Type String)
'          Label10: '"Business Phone:"' (Type String)
'          Label11: '"Mobile Phone:"' (Type String)
'          Label14: '"Email Address:"' (Type String)
'          Label15: '"Alternate Email Address:"' (Type String)

Upaya untuk mengambil data sumber daya dari IDictionaryEnumerator.Value properti dapat melemparkan pengecualian berikut:

Biasanya, pengecualian ini dilemparkan jika file .resources telah dimodifikasi secara manual, jika rakitan di mana jenis didefinisikan belum disertakan dengan aplikasi atau telah dihapus secara tidak sengaja, atau jika rakitan adalah versi lama yang mendahului jenis. Jika salah satu pengecualian ini dilemparkan, Anda dapat mengambil sumber daya dengan menghitung setiap sumber daya dan memanggil GetResourceData metode , seperti yang ditunjukkan bagian berikut. Pendekatan ini memberi Anda beberapa informasi tentang jenis data yang IDictionaryEnumerator.Value coba dikembalikan properti.

Mengambil sumber daya berdasarkan nama dengan GetResourceData

Pendekatan kedua untuk menghitung sumber daya dalam file .resources juga melibatkan navigasi melalui sumber daya dalam file dengan memanggil IDictionaryEnumerator.MoveNext metode . Untuk setiap sumber daya, Anda mengambil nama sumber daya dari IDictionaryEnumerator.Key properti , yang kemudian diteruskan ke GetResourceData(String, String, Byte[]) metode untuk mengambil data sumber daya. Ini dikembalikan sebagai array byte dalam resourceData argumen.

Pendekatan ini lebih canggung daripada mengambil nama dan nilai sumber daya dari IDictionaryEnumerator.Key properti dan IDictionaryEnumerator.Value , karena mengembalikan byte aktual yang membentuk nilai sumber daya. Namun, jika upaya untuk mengambil sumber daya melemparkan pengecualian, metode ini GetResourceData dapat membantu mengidentifikasi sumber pengecualian dengan menyediakan informasi tentang jenis data sumber daya. Untuk informasi selengkapnya tentang string yang menunjukkan jenis data sumber daya, lihat GetResourceData.

Contoh berikut menggambarkan cara menggunakan pendekatan ini untuk mengambil sumber daya dan menangani pengecualian apa pun yang dilemparkan. Ini secara terprogram membuat file .resources biner yang berisi empat string, satu Boolean, satu bilangan bulat, dan satu bitmap. Untuk menjalankan contoh, lakukan hal berikut:

  1. Kompilasi dan jalankan kode sumber berikut, yang membuat file .resources bernama ContactResources.resources.

    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Resources;
    using System.Runtime.Versioning;
    
    public class Example5
    {
        [SupportedOSPlatform("windows")]
        public static void Run()
        {
            // Bitmap as stream.
            MemoryStream bitmapStream = new MemoryStream();
            Bitmap bmp = new Bitmap(@".\ContactsIcon.jpg");
            bmp.Save(bitmapStream, ImageFormat.Jpeg);
    
            // Define resources to be written.
            using (ResourceWriter rw = new ResourceWriter(@".\ContactResources.resources"))
            {
                rw.AddResource("Title", "Contact List");
                rw.AddResource("NColumns", 5);
                rw.AddResource("Icon", bitmapStream);
                rw.AddResource("Header1", "Name");
                rw.AddResource("Header2", "City");
                rw.AddResource("Header3", "State");
                rw.AddResource("ClientVersion", true);
                rw.Generate();
            }
        }
    }
    

    File kode sumber diberi nama CreateResources.cs. Anda dapat mengkompilasinya di C# dengan menggunakan perintah berikut:

    csc CreateResources.cs /r:library.dll
    
  2. Kompilasi dan jalankan kode berikut untuk menghitung sumber daya dalam file ContactResources.resources.

    using System;
    using System.Collections;
    using System.Drawing;
    using System.IO;
    using System.Resources;
    using System.Runtime.Versioning;
    
    public class Example6
    {
        [SupportedOSPlatform("windows")]
        public static void Run()
        {
            ResourceReader rdr = new ResourceReader(@".\ContactResources.resources");
            IDictionaryEnumerator dict = rdr.GetEnumerator();
            while (dict.MoveNext())
            {
                Console.WriteLine("Resource Name: {0}", dict.Key);
                try
                {
                    Console.WriteLine("   Value: {0}", dict.Value);
                }
                catch (FileNotFoundException)
                {
                    Console.WriteLine("   Exception: A file cannot be found.");
                    DisplayResourceInfo(rdr, (string)dict.Key, false);
                }
                catch (FormatException)
                {
                    Console.WriteLine("   Exception: Corrupted data.");
                    DisplayResourceInfo(rdr, (string)dict.Key, true);
                }
                catch (TypeLoadException)
                {
                    Console.WriteLine("   Exception: Cannot load the data type.");
                    DisplayResourceInfo(rdr, (string)dict.Key, false);
                }
            }
        }
    
        [SupportedOSPlatform("windows")]
        private static void DisplayResourceInfo(ResourceReader rr,
                                        string key, bool loaded)
        {
            string dataType = null;
            byte[] data = null;
            rr.GetResourceData(key, out dataType, out data);
    
            // Display the data type.
            Console.WriteLine("   Data Type: {0}", dataType);
            // Display the bytes that form the available data.      
            Console.Write("   Data: ");
            int lines = 0;
            foreach (var dataItem in data)
            {
                lines++;
                Console.Write("{0:X2} ", dataItem);
                if (lines % 25 == 0)
                    Console.Write("\n         ");
            }
            Console.WriteLine();
            // Try to recreate current state of data.
            // Do: Bitmap, DateTimeTZI
            switch (dataType)
            {
                // Handle internally serialized string data (ResourceTypeCode members).
                case "ResourceTypeCode.String":
                    BinaryReader reader = new BinaryReader(new MemoryStream(data));
                    string binData = reader.ReadString();
                    Console.WriteLine("   Recreated Value: {0}", binData);
                    break;
                case "ResourceTypeCode.Int32":
                    Console.WriteLine("   Recreated Value: {0}",
                                      BitConverter.ToInt32(data, 0));
                    break;
                case "ResourceTypeCode.Boolean":
                    Console.WriteLine("   Recreated Value: {0}",
                                      BitConverter.ToBoolean(data, 0));
                    break;
                // .jpeg image stored as a stream.
                case "ResourceTypeCode.Stream":
                    const int OFFSET = 4;
                    int size = BitConverter.ToInt32(data, 0);
                    Bitmap value1 = new Bitmap(new MemoryStream(data, OFFSET, size));
                    Console.WriteLine("   Recreated Value: {0}", value1);
                    break;
                default:
                    break;
            }
            Console.WriteLine();
        }
    }
    

    Setelah memodifikasi kode sumber (misalnya, dengan sengaja melemparkan FormatException di akhir try blok), Anda dapat menjalankan contoh untuk melihat bagaimana panggilan memungkinkan GetResourceData Anda mengambil atau membuat ulang beberapa informasi sumber daya.