System.Resources.ResourceReader – třída
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Důležité
Volání metod z této třídy s nedůvěryhodnými daty představuje bezpečnostní riziko. Volejte metody z této třídy pouze s důvěryhodnými daty. Další informace naleznete v tématu Ověření všech vstupů.
Třída ResourceReader poskytuje standardní implementaci IResourceReader rozhraní. Instance ResourceReader představuje samostatný soubor .resources nebo soubor .resources, který je vložen do sestavení. Slouží k vytvoření výčtu prostředků v souboru .resources a načtení párů název/hodnota. Liší se od ResourceManager třídy, která se používá k načtení zadaných pojmenovaných prostředků ze souboru .resources, který je vložen do sestavení. Třída ResourceManager se používá k načtení prostředků, jejichž názvy jsou známy předem, zatímco ResourceReader třída je užitečná pro načtení prostředků, jejichž počet nebo přesné názvy nejsou známy v době kompilace. Aplikace může například použít soubor prostředků k ukládání konfiguračních informací uspořádaných do oddílů a položek v oddílu, kde počet oddílů nebo položek v oddílu není předem znám. Prostředky se pak dají pojmenovat obecně (například Section1
, Section1Item1
Section1Item2
, atd.) a načíst pomocí objektuResourceReader.
Důležité
Tento typ implementuje IDisposable rozhraní. Jakmile typ dokončíte, měli byste ho odstranit buď přímo, nebo nepřímo. Chcete-li odstranit typ přímo, zavolejte jeho Dispose metodu try
/catch
v bloku. Pokud ho chcete zlikvidovat nepřímo, použijte konstruktor jazyka, například using
(v jazyce C#) nebo Using
(v jazyce Visual Basic). Další informace najdete v části Použití objektu, který implementuje IDisposable v IDisposable dokumentaci k rozhraní.
Vytvoření instance objektu ResourceReader
Soubor .resources je binární soubor, který byl zkompilován z textového souboru nebo souboru XML .resx Resgen.exe (Generátor souborů prostředků). Objekt ResourceReader může představovat samostatný soubor .resources nebo soubor .resources, který byl vložen do sestavení.
K vytvoření instance objektu ResourceReader , který čte ze samostatného souboru .resources, použijte ResourceReader konstruktor třídy se vstupním datovým proudem nebo řetězcem, který obsahuje název souboru .resources. Následující příklad ukazuje oba přístupy. První vytvoří instanci objektu ResourceReader , který představuje soubor .resources pojmenovaný Resources1.resources
pomocí názvu souboru. Druhý vytvoří instanci objektu ResourceReader , který představuje soubor .resources pojmenovaný Resources2.resources
pomocí datového proudu vytvořeného ze souboru.
// 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)
Chcete-li vytvořit ResourceReader objekt, který představuje vložený soubor .resources, vytvořte instanci Assembly objektu ze sestavení, ve kterém je vložen soubor .resources. Jeho Assembly.GetManifestResourceStream metoda vrátí Stream objekt, který lze předat konstruktoru ResourceReader(Stream) . Následující příklad vytvoří instanci objektu ResourceReader , který představuje vložený soubor .resources.
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)
Vytvoření výčtu prostředků objektu ResourceReader
Chcete-li vytvořit výčet prostředků v souboru .resources, zavoláte metodu GetEnumerator , která vrátí System.Collections.IDictionaryEnumerator objekt. Zavoláte metodu IDictionaryEnumerator.MoveNext
, která se má přesunout z jednoho prostředku na další. Metoda vrátí false
, když byly všechny prostředky v souboru .resources výčtu.
Poznámka:
ResourceReader Ačkoli třída implementuje IEnumerable rozhraní a metoduIEnumerable.GetEnumerator, ResourceReader.GetEnumerator metoda neposkytuje implementaciIEnumerable.GetEnumerator. ResourceReader.GetEnumerator Místo toho metoda vrátí IDictionaryEnumerator objekt rozhraní, který poskytuje přístup ke dvojici název/hodnota každého prostředku.
Jednotlivé prostředky v kolekci můžete načíst dvěma způsoby:
Každý prostředek v kolekci System.Collections.IDictionaryEnumerator můžete iterovat a použít System.Collections.IDictionaryEnumerator vlastnosti k načtení názvu a hodnoty prostředku. Tuto techniku doporučujeme, když jsou všechny prostředky stejného typu nebo znáte datový typ každého prostředku.
Název každého prostředku můžete načíst, když iterujete System.Collections.IDictionaryEnumerator kolekci a zavoláte metodu GetResourceData pro načtení dat prostředku. Tento přístup doporučujeme, když neznáte datový typ každého prostředku nebo pokud předchozí přístup vyvolá výjimky.
Načtení prostředků pomocí vlastností IDictionaryEnumerator
První metoda vytvoření výčtu prostředků v souboru .resources zahrnuje přímé načtení dvojice název/hodnota každého prostředku. Po volání IDictionaryEnumerator.MoveNext
metody pro přesunutí na každý prostředek v kolekci můžete načíst název prostředku z IDictionaryEnumerator.Key vlastnosti a data o prostředcích IDictionaryEnumerator.Value z vlastnosti.
Následující příklad ukazuje, jak pomocí a IDictionaryEnumerator.Value vlastností načíst název a hodnotu každého prostředku v souboru IDictionaryEnumerator.Key .resources. Pokud chcete spustit příklad, vytvořte následující textový soubor s názvem ApplicationResources.txt, který definuje prostředky řetězců.
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:"
Potom můžete textový soubor prostředků převést na binární soubor s názvem ApplicationResources.resources pomocí následujícího příkazu:
resgen ApplicationResources.txt
Následující příklad pak použije ResourceReader třídu k vytvoření výčtu jednotlivých prostředků v samostatném binárním souboru .resources a k zobrazení názvu klíče a odpovídající hodnoty.
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)
Pokus o načtení dat prostředků z IDictionaryEnumerator.Value vlastnosti může vyvolat následující výjimky:
- A FormatException , pokud data nejsou v očekávaném formátu.
- A FileNotFoundException pokud sestavení obsahující typ, do kterého data patří, nelze najít.
- Typ TypeLoadException , do kterého data patří, nelze najít.
Tyto výjimky jsou obvykle vyvolány v případě, že byl soubor .resources upraven ručně, pokud sestavení, ve kterém je definován typ, buď není součástí aplikace, nebo byla neúmyslně odstraněna, nebo pokud je sestavení starší verzí, která předchází typu. Pokud je vyvolána jedna z těchto výjimek, můžete načíst prostředky výčetm jednotlivých prostředků a voláním GetResourceData metody, jak ukazuje následující část. Tento přístup poskytuje některé informace o datovém typu, který se IDictionaryEnumerator.Value vlastnost pokusila vrátit.
Načtení prostředků podle názvu pomocí GetResourceData
Druhý přístup k vytvoření výčtu prostředků v souboru .resources zahrnuje také procházení prostředků v souboru voláním IDictionaryEnumerator.MoveNext
metody. Pro každý prostředek načtete název prostředku z IDictionaryEnumerator.Key vlastnosti, která se pak předá GetResourceData(String, String, Byte[]) metodě pro načtení dat prostředku. Vrátí se jako pole bajtů v argumentu resourceData
.
Tento přístup je složitější než načtení názvu a hodnoty prostředku z IDictionaryEnumerator.Key vlastností IDictionaryEnumerator.Value , protože vrací skutečné bajty, které tvoří hodnotu prostředku. Pokud však pokus o načtení prostředku vyvolá výjimku, GetResourceData může metoda pomoct identifikovat zdroj výjimky poskytnutím informací o datovém typu prostředku. Další informace o řetězci, který označuje datový typ prostředku, naleznete v tématu GetResourceData.
Následující příklad ukazuje, jak pomocí tohoto přístupu načíst prostředky a zpracovat všechny výjimky, které jsou vyvolány. Programově vytvoří binární soubor .resources, který obsahuje čtyři řetězce, jednu logickou hodnotu, jedno celé číslo a jeden rastrový obrázek. Pokud chcete spustit příklad, postupujte takto:
Zkompilujte a spusťte následující zdrojový kód, který vytvoří soubor .resources s názvem 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(); } } }
Soubor zdrojového kódu má název CreateResources.cs. V jazyce C# ho můžete zkompilovat pomocí následujícího příkazu:
csc CreateResources.cs /r:library.dll
Zkompilujte a spusťte následující kód pro vytvoření výčtu prostředků v souboru 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(); } }
Po úpravě zdrojového kódu (například záměrně vyvoláním FormatException na konci
try
bloku) můžete spustit příklad a podívat se, jak GetResourceData volání umožňující načtení nebo opětovné vytvoření některých informací o prostředku.