Este artículo se tradujo automáticamente. Para ver el artículo en inglés, active la casilla Inglés. Además, puede mostrar el texto en inglés en una ventana emergente si mueve el puntero del mouse sobre el texto.
Traducción
Inglés

Clase ResourceReader

 

Publicado: octubre de 2016

Enumera los recursos en un archivo binario de recursos (.resources) leyendo pares secuenciales de nombre/valor del recurso.

Nota de seguridad: llamar a métodos en esta clase con datos que no son de confianza conlleva un riesgo de seguridad. Llame a los métodos en la clase solo con datos de confianza. Para obtener más información, consulte Riesgos de seguridad de datos que no son de confianza.

Espacio de nombres:   System.Resources
Ensamblado:  mscorlib (en mscorlib.dll)

System.Object
  System.Resources.ResourceReader

[ComVisibleAttribute(true)]
public sealed class ResourceReader : IResourceReader, IEnumerable, 
	IDisposable

NombreDescripción
System_CAPS_pubmethodResourceReader(Stream)

Inicializa una nueva instancia de la clase ResourceReader para el flujo especificado.

System_CAPS_pubmethodResourceReader(String)

Inicializa una nueva instancia de la clase ResourceReader para el archivo de recursos con nombre especificado.

NombreDescripción
System_CAPS_pubmethodClose()

Libera todos los recursos del sistema operativo asociados a este objeto ResourceReader.

System_CAPS_pubmethodDispose()

Libera todos los recursos usados por la instancia actual de la clase ResourceReader.

System_CAPS_pubmethodEquals(Object)

Determina si el objeto especificado es igual al objeto actual.(Heredado de Object).

System_CAPS_pubmethodGetEnumerator()

Devuelve un enumerador para este objeto ResourceReader.

System_CAPS_pubmethodGetHashCode()

Sirve como la función hash predeterminada.(Heredado de Object).

System_CAPS_pubmethodGetResourceData(String, String, Byte[])

Recupera el nombre de tipo y datos de un recurso con nombre a partir de un archivo de recursos o secuencia abiertos.

System_CAPS_pubmethodGetType()

Obtiene el Type de la instancia actual.(Heredado de Object).

System_CAPS_pubmethodToString()

Devuelve una cadena que representa al objeto actual. (Heredado de Object).

NombreDescripción
System_CAPS_pubinterfaceSystem_CAPS_privmethodIEnumerable.GetEnumerator()

Devuelve un enumerador para este objeto ResourceReader.

NombreDescripción
System_CAPS_pubmethodAsParallel()

Sobrecargado. Habilita la paralelización de una consulta.(Definido por ParallelEnumerable).

System_CAPS_pubmethodAsQueryable()

Sobrecargado. Convierte un IEnumerable para un IQueryable.(Definido por Queryable).

System_CAPS_pubmethodCast<TResult>()

Convierte los elementos de un IEnumerable al tipo especificado.(Definido por Enumerable).

System_CAPS_pubmethodOfType<TResult>()

Filtra los elementos de un IEnumerable basado en un tipo especificado.(Definido por Enumerable).

The T:System.Resources.ResourceReader class provides a standard implementation of the T:System.Resources.IResourceReader interface. A T:System.Resources.ResourceReader instance represents either a standalone .resources file or a .resources file that is embedded in an assembly. It is used to enumerate the resources in a .resources file and retrieve its name/value pairs. It differs from the T:System.Resources.ResourceManager class, which is used to retrieve specified named resources from a .resources file that is embedded in an assembly. The T:System.Resources.ResourceManager class is used to retrieve resources whose names are known in advance, whereas the T:System.Resources.ResourceReader class is useful for retrieving resources whose number or precise names are not known at compile time. For example, an application may use a resources file to store configuration information that is organized into sections and items in a section, where the number of sections or items in a section is not known in advance. Resources can then be named generically (such as Section1, Section1Item1, Section1Item2, and so on) and retrieved by using a T:System.Resources.ResourceReader object.

System_CAPS_importantImportante

This type implements the T:System.IDisposable interface. When you have finished using the type, you should dispose of it either directly or indirectly. To dispose of the type directly, call its M:System.IDisposable.Dispose method in a try/catch block. To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic). For more information, see the “Using an Object that Implements IDisposable” section in the T:System.IDisposable interface topic.

For more information about using the T:System.Resources.ResourceReader class, see the following sections:

A .resources file is a binary file that has been compiled from either a text file or an XML .resx file by Resgen.exe (Resource File Generator). A T:System.Resources.ResourceReader object can represent either a standalone .resources file or a .resources file that has been embedded in an assembly.

To instantiate a T:System.Resources.ResourceReader object that reads from a standalone .resources file, use the T:System.Resources.ResourceReader class constructor with either an input stream or a string that contains the .resources file name. The following example illustrates both approaches. The first instantiates a T:System.Resources.ResourceReader object that represents a .resources file named Resources1.resources by using its file name. The second instantiates a T:System.Resources.ResourceReader object that represents a .resources file named Resources2.resources by using a stream created from the 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);      

To create a T:System.Resources.ResourceReader object that represents an embedded .resources file, instantiate an T:System.Reflection.Assembly object from the assembly in which the .resources file is embedded. Its M:System.Reflection.Assembly.GetManifestResourceStream(System.Type,System.String) method returns a T:System.IO.Stream object that can be passed to the M:System.Resources.ResourceReader.#ctor(System.IO.Stream) constructor. The following example instantiates a T:System.Resources.ResourceReader object that represents an embedded .resources file.

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

To enumerate the resources in a .resources file, you call the M:System.Resources.ResourceReader.GetEnumerator method, which returns an T:System.Collections.IDictionaryEnumerator object. You call the IDictionaryEnumerator.MoveNext method to move from one resource to the next. The method returns false when all the resources in the .resources file have been enumerated.

System_CAPS_noteNota

Although the T:System.Resources.ResourceReader class implements the T:System.Collections.IEnumerable interface and the M:System.Collections.IEnumerable.GetEnumerator method, the M:System.Resources.ResourceReader.GetEnumerator method does not provide the M:System.Collections.IEnumerable.GetEnumerator implementation. Instead, the M:System.Resources.ResourceReader.GetEnumerator method returns an T:System.Collections.IDictionaryEnumerator interface object that provides access to each resource's name/value pair.

You can retrieve the individual resources in the collection in two ways:

  • You can iterate each resource in the T:System.Collections.IDictionaryEnumerator collection and use T:System.Collections.IDictionaryEnumerator properties to retrieve the resource name and value. We recommend this technique when all the resources are of the same type, or you know the data type of each resource.

  • You can retrieve the name of each resource when you iterate the T:System.Collections.IDictionaryEnumerator collection and call the M:System.Resources.ResourceReader.GetResourceData(System.String,System.String@,System.Byte[]@) method to retrieve the resource's data. We recommend this approach when you do not know the data type of each resource or if the previous approach throws exceptions.

The first method of enumerating the resources in a .resources file involves directly retrieving each resource's name/value pair. After you call the IDictionaryEnumerator.MoveNext method to move to each resource in the collection, you can retrieve the resource name from the P:System.Collections.IDictionaryEnumerator.Key property and the resource data from the P:System.Collections.IDictionaryEnumerator.Value property.

The following example shows how to retrieve the name and value of each resource in a .resources file by using the P:System.Collections.IDictionaryEnumerator.Key and P:System.Collections.IDictionaryEnumerator.Value properties. To run the example, create the following text file named ApplicationResources.txt to define string resources.

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

You can then convert the text resource file to a binary file named ApplicationResources.resources by using the following command:

resgen ApplicationResources.txt

The following example then uses the T:System.Resources.ResourceReader class to enumerate each resource in the standalone binary .resources file and to display its key name and corresponding value.

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

public class Example
{
   public static void Main()
   {
      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)

The attempt to retrieve resource data from the P:System.Collections.IDictionaryEnumerator.Value property can throw the following exceptions:

  • A T:System.FormatException if the data is not in the expected format.

  • A T:System.IO.FileNotFoundException if the assembly that contains the type to which the data belongs cannot be found.

  • A T:System.TypeLoadException if the type to which the data belongs cannot be cannot be found.

Typically, these exceptions are thrown if the .resources file has been modified manually, if the assembly in which a type is defined has either not been included with an application or has been inadvertently deleted, or if the assembly is an older version that predates a type. If one of these exceptions is thrown, you can retrieve resources by enumerating each resource and calling the M:System.Resources.ResourceReader.GetResourceData(System.String,System.String@,System.Byte[]@) method, as the following section shows. This approach provides you with some information about the data type that the P:System.Collections.IDictionaryEnumerator.Value property attempted to return.

The second approach to enumerating resources in a .resources file also involves navigating through the resources in the file by calling the IDictionaryEnumerator.MoveNext method. For each resource, you retrieve the resource's name from the P:System.Collections.IDictionaryEnumerator.Key property, which is then passed to the M:System.Resources.ResourceReader.GetResourceData(System.String,System.String@,System.Byte[]@) method to retrieve the resource's data. This is returned as a byte array in the resourceData argument.

This approach is more awkward than retrieving the resource name and value from the P:System.Collections.IDictionaryEnumerator.Key and P:System.Collections.IDictionaryEnumerator.Value properties, because it returns the actual bytes that form the resource value. However, if the attempt to retrieve the resource throws an exception, the M:System.Resources.ResourceReader.GetResourceData(System.String,System.String@,System.Byte[]@) method can help identify the source of the exception by supplying information about the resource's data type. For more information about the string that indicates the resource's data type, see M:System.Resources.ResourceReader.GetResourceData(System.String,System.String@,System.Byte[]@).

The following example illustrates how to use this approach to retrieve resources and to handle any exceptions that are thrown. It programmatically creates a binary .resources file that contains four strings, one Boolean, one integer, one bitmap, and one custom DateTimeTZI object. To run the example, do the following:

  1. Create an assembly named Library.dll that contains the DateTimeTZI structure. The following is the source code for the assembly.

    using System;
    
    [Serializable] public struct DateTimeTZI
    {
      DateTime Date;
      TimeZoneInfo TimeZone;
    
      public DateTimeTZI(DateTime date, TimeZoneInfo tz)
      {
         this.Date = date;
         this.TimeZone = tz;
      }
    
       public override string ToString()
       {
         return String.Format("{0:dd/MM/yyyy hh:mm:ss tt} {1}", 
                              Date, TimeZone.StandardName);
       }
    }
    

    Compile the source code in C# by using the following command:

    csc /t:library library.cs
    

    Or, you can compile it in Visual Basic by using the following command:

    vbc library.vb /t:library
    
  2. Compile and execute the following source code, which creates a .resources file named ContactResources.resources.

    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Resources;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    
    
    public class Example
    {
       public static void Main()
       {
          // 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("VersionDate", new DateTimeTZI(
                            new DateTime(2012, 5, 18),  
                            TimeZoneInfo.Local));
             rw.AddResource("ClientVersion", true);
             rw.Generate();
          }
       }
    }
    

    The source code file is named CreateResources.cs. You can compile it in C# by using the following command:

    csc CreateResources.cs /r:library.dll
    

    Or, you can compile it in Visual Basic by using the following command:

    vbc CreateResources.vb /r:library.dll
    
  3. Compile and run the following code to enumerate the resources in the ContactResources.resources file.

    using System;
    using System.Collections;
    using System.Drawing;
    using System.IO;
    using System.Resources;
    using System.Runtime.Serialization.Formatters.Binary;
    
    public class Example
    {
       public static void Main()
       {
          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);   
             }
          } 
       }
    
       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;
             // Our only other type is DateTimeTZI.
             default:
                // No point in deserializing data if the type is unavailable.
                if (dataType.Contains("DateTimeTZI") && loaded) { 
                   BinaryFormatter binFmt = new BinaryFormatter();
                   object value2 = binFmt.Deserialize(new MemoryStream(data));
                   Console.WriteLine("   Recreated Value: {0}", value2);
                }    
                break;
          }
          Console.WriteLine();
       }
    }
    

    After modifying the source code (for example, by deliberately throwing a T:System.FormatException at the end of the try block) or renaming the Library.dll assembly so that it is unavailable at runtime, you can run the example to see how calls to M:System.Resources.ResourceReader.GetResourceData(System.String,System.String@,System.Byte[]@) enable you to retrieve or recreate some resource information.

.NET Framework
Disponible desde 1.1

Cualquier miembro ( Compartido en Visual Basic) estático público de este tipo es seguro para subprocesos. No se garantiza que los miembros de instancia sean seguros para subprocesos.

Volver al principio
Mostrar: