System.Resources.ResourceReader osztály

Megjegyzés

Ez a cikk kiegészítő megjegyzéseket tartalmaz az API referenciadokumentációjához.

Fontos

Az osztályból származó metódusok nem megbízható adatokkal való meghívása biztonsági kockázatot jelent. Az osztály metódusait csak megbízható adatokkal hívja meg. További információ: Minden bemenet ellenőrzése.

A ResourceReader osztály a IResourceReader felület szabványos implementációját biztosítja. A ResourceReader-példány egy önálló .resources-fájlt vagy egy olyan .resources-fájlt jelöl, amely egy egységbe van ágyazva. A .resources-fájlban lévő erőforrások számbavételére és a név/érték párok lekérésére szolgál. Különbözik a ResourceManager osztálytól, amely egy szerelvénybe beágyazott .resources-fájlból kéri le a megadott elnevezett erőforrásokat. A ResourceManager osztály olyan erőforrások lekérésére szolgál, amelyek neve előre ismert, míg a ResourceReader osztály olyan erőforrások lekéréséhez hasznos, amelyek száma vagy pontos neve nem ismert a fordításkor. Egy alkalmazás például egy erőforrásfájllal tárolhatja a szakasz szakaszaiba és elemeibe rendezett konfigurációs információkat, ahol egy szakasz szakaszainak vagy elemeinek száma előre nem ismert. Az erőforrások ezután általánosan elnevezhetők (például Section1, Section1Item1, Section1Item2stb.), és lekérhetők egy ResourceReader objektum használatával.

Fontos

Ez a típus implementálja a IDisposable felületet. Ha befejezte a típus használatát, közvetlenül vagy közvetve kell megsemmisítenie. A típus közvetlen ártalmatlanításához hívja meg a Dispose metódust egy try/catch blokkban. Ha közvetve szeretné megsemmisíteni, használjon olyan nyelvi szerkezetet, mint a using (C#-ban) vagy Using (a Visual Basicben). További információt a IDisposable felület dokumentációjának "Az IDisposable-t megvalósító objektum használata" című szakaszában talál.

ResourceReader-objektum példányosítása

A .resources-fájlok olyan bináris fájlok, amelyeket a Resgen.exe (Erőforrásfájl-generátor)készítettek egy szövegfájlból vagy XML .resx fájlból. Egy ResourceReader objektum önálló .resources-fájlt vagy .resources-fájlt jelölhet, amely egy szerelvénybe lett beágyazva.

Ha egy különálló .resources-fájlból beolvasott ResourceReader objektumot szeretne létrehozni, használja a ResourceReader osztálykonstruktort egy bemeneti adatfolyammal vagy egy .resources fájlnevet tartalmazó sztringgel. Az alábbi példa mindkét megközelítést szemlélteti. Az első példányosít egy ResourceReader objektumot, amely egy Resources1.resources nevű .resources-fájlt jelöl a fájlnév használatával. A második példányosít egy ResourceReader objektumot, amely egy Resources2.resources nevű .resources-fájlt jelöl a fájlból létrehozott stream használatával.

// 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)

Beágyazott .resources-fájlokat képviselő ResourceReader objektum létrehozásához hozzon létre egy Assembly objektumot abból a szerelvényből, amelyben a .resources fájl beágyazva van. A Assembly.GetManifestResourceStream metódus egy Stream objektumot ad vissza, amely átadható a ResourceReader(Stream) konstruktornak. Az alábbi példa egy beágyazott .resources fájlt képviselő ResourceReader objektumot hoz létre.

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)

ResourceReader-objektum erőforrásainak számbavétele

Az erőforrások .resources fájlban való számbavételéhez hívja meg a GetEnumerator metódust, amely egy System.Collections.IDictionaryEnumerator objektumot ad vissza. A IDictionaryEnumerator.MoveNext metódus meghívásával válthat az egyik erőforrásról a másikra. A metódus false a .resources fájl összes erőforrásának számbavétele után adja vissza.

Megjegyzés

Bár a ResourceReader osztály implementálja a IEnumerable felületet és a IEnumerable.GetEnumerator metódust, a ResourceReader.GetEnumerator metódus nem biztosítja a IEnumerable.GetEnumerator implementációt. Ehelyett a ResourceReader.GetEnumerator metódus egy IDictionaryEnumerator felületobjektumot ad vissza, amely hozzáférést biztosít az egyes erőforrások név-érték párjaihoz.

A gyűjtemény egyes erőforrásai kétféleképpen kérhetők le:

  • A System.Collections.IDictionaryEnumerator gyűjtemény minden erőforrását iterálhatja, és System.Collections.IDictionaryEnumerator tulajdonságok használatával lekérheti az erőforrás nevét és értékét. Ezt a technikát akkor javasoljuk, ha az összes erőforrás azonos típusú, vagy ismeri az egyes erőforrások adattípusát.

  • Az egyes erőforrások nevét az System.Collections.IDictionaryEnumerator-gyűjtemény iterálásakor lekérheti, és meghívhatja a GetResourceData metódust az erőforrás adatainak lekéréséhez. Ezt a megközelítést akkor javasoljuk, ha nem ismeri az egyes erőforrások adattípusát, vagy ha az előző megközelítés kivételeket eredményez.

Erőforrások lekérése az IDictionaryEnumerator tulajdonságaival

Az erőforrások .resources fájlban való számbavételének első módszere az egyes erőforrások nevének/értékpárjának közvetlen lekérése. Miután meghívta a IDictionaryEnumerator.MoveNext metódust, hogy a gyűjtemény minden egyes erőforrására lépjen, lekérheti az erőforrás nevét a IDictionaryEnumerator.Key tulajdonságból és az erőforrás-adatokat a IDictionaryEnumerator.Value tulajdonságból.

Az alábbi példa bemutatja, hogyan kérdezheti le az egyes erőforrások nevét és értékét egy .resources fájlban a IDictionaryEnumerator.Key és IDictionaryEnumerator.Value tulajdonságok használatával. A példa futtatásához hozzon létre egy ApplicationResources.txt nevű szövegfájlt a sztringerőforrások definiálásához.

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:"

Ezután az alábbi paranccsal konvertálhatja a szöveges erőforrásfájlt egy ApplicationResources.resources nevű bináris fájllá:

resgen ApplicationResources.txt

Az alábbi példa ezután a ResourceReader osztály használatával számba veszi az egyes erőforrásokat az önálló bináris .resources fájlban, és megjeleníti annak kulcsnevét és megfelelő értékét.

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($"   {dict.Key}: '{dict.Value}' (Type {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)

Az erőforrásadatok IDictionaryEnumerator.Value tulajdonságból való lekérésének kísérlete a következő kivételeket okozhatja:

Ezek a kivételek általában akkor jelentkeznek, ha a .resources fájlt manuálisan módosították, ha a típust definiáló szerelvény vagy nem szerepel egy alkalmazásban, vagy véletlenül törölték, vagy ha a szerelvény egy régebbi verzió, amely megelőzi a típust. Ha a kivételek egyike ki van dobva, az erőforrásokat az egyes erőforrások számbavételével és a GetResourceData metódus meghívásával is lekérheti, ahogy az alábbi szakasz is mutatja. Ez a megközelítés információt nyújt arról az adattípusról, amelyet a IDictionaryEnumerator.Value tulajdonság megpróbált visszaadni.

Erőforrások lekérése név szerint a GetResourceData használatával

A .resources-fájlokban lévő erőforrások számbavételének második megközelítése magában foglalja a fájl erőforrásainak navigálását is a IDictionaryEnumerator.MoveNext metódus meghívásával. Minden erőforrás esetében lekéri az erőforrás nevét a IDictionaryEnumerator.Key tulajdonságból, amelyet a rendszer a GetResourceData(String, String, Byte[]) metódusnak ad át az erőforrás adatainak lekéréséhez. Ezt a függvény a resourceData argumentumban bájttömbként adja vissza.

Ez a módszer kínosabb, mint az erőforrás nevének és értékének lekérése a IDictionaryEnumerator.Key és IDictionaryEnumerator.Value tulajdonságokból, mivel az erőforrás értékét alkotó tényleges bájtokat adja vissza. Ha azonban az erőforrás lekérésére tett kísérlet kivételt eredményez, a GetResourceData metódus segíthet azonosítani a kivétel forrását az erőforrás adattípusára vonatkozó információk megadásával. Az erőforrás adattípusát jelző sztringről további információt a GetResourceDatacímű témakörben talál.

Az alábbi példa bemutatja, hogyan használható ez a megközelítés az erőforrások lekérésére és a kidobott kivételek kezelésére. Programozott módon létrehoz egy bináris .resources fájlt, amely négy sztringet, egy logikai értéket, egy egész számot és egy bitképet tartalmaz. A példa futtatásához tegye a következőket:

  1. Fordítsa le és hajtsa végre a következő forráskódot, amely létrehoz egy ContactResources.resources nevű .resources fájlt.

    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();
            }
        }
    }
    

    A forráskódfájl neve CreateResources.cs. A C#-ban a következő parancsot használva fordíthatja le:

    csc CreateResources.cs /r:library.dll
    
  2. A ContactResources.resources fájlban lévő erőforrások számbavételéhez fordítsa le és futtassa a következő kódot.

    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: {dict.Key}");
                try
                {
                    Console.WriteLine($"   Value: {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: {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: {binData}");
                    break;
                case "ResourceTypeCode.Int32":
                    Console.WriteLine($"   Recreated Value: {BitConverter.ToInt32(data, 0)}");
                    break;
                case "ResourceTypeCode.Boolean":
                    Console.WriteLine($"   Recreated Value: {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: {value1}");
                    break;
                default:
                    break;
            }
            Console.WriteLine();
        }
    }
    

    A forráskód módosítása után (például ha szándékosan dob egy FormatException a try blokk végére), futtathatja a példát, hogy lássa, hogyan lehet GetResourceData hívásokkal lekérni vagy újra létrehozni néhány erőforrás-információt.