System.Resources.ResourceReader 클래스

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

Important

신뢰할 수 없는 데이터로 이 클래스에서 메서드를 호출하는 것은 보안상 위험합니다. 신뢰할 수 있는 데이터로만 이 클래스에서 메서드를 호출하세요. 자세한 내용은 모든 입력 유효성 검사를 참조 하세요.

클래스는 ResourceReader 인터페이스의 표준 구현을 IResourceReader 제공합니다. 인스턴스는 ResourceReader 독립 실행형 .resources 파일 또는 어셈블리에 포함된 .resources 파일을 나타냅니다. .resources 파일에서 리소스를 열거하고 해당 이름/값 쌍을 검색하는 데 사용됩니다. 어셈블리에 ResourceManager 포함된 .resources 파일에서 지정된 명명된 리소스를 검색하는 데 사용되는 클래스와 다릅니다. 클래스 ResourceManager 는 이름이 미리 알려진 리소스를 검색하는 데 사용되는 반면 ResourceReader , 클래스는 컴파일 시간에 번호 또는 정확한 이름을 알 수 없는 리소스를 검색하는 데 유용합니다. 예를 들어, 애플리케이션 섹션과 섹션으로, 여기서는 섹션의 항목 섹션에 알 수 없는 사전에 항목으로 구성 되어 있는 구성 정보를 저장할 리소스 파일을 사용할 수 있습니다. 그런 다음 리소스의 이름을 일반적으로 지정하고(예: Section1, Section1Item1Section1Item2등) 개체를 사용하여 ResourceReader 검색할 수 있습니다.

Important

이 형식이 구현 하는 IDisposable 인터페이스입니다. 형식을 사용 하 여 마쳤으면 직접 또는 간접적으로의 삭제 해야 있습니다. 직접 형식의 dispose 호출 해당 Dispose 의 메서드를 try/catch 블록입니다. 삭제 하지 직접, 언어 구문 같은 사용 using (C#에서) 또는 Using (Visual Basic에서는). 자세한 내용은 인터페이스 설명서의 "IDisposable을 구현하는 개체 사용" 섹션을 IDisposable 참조하세요.

ResourceReader 개체 인스턴스화

.resources 파일은 Resgen.exe(리소스 파일 생성기)에 의해 텍스트 파일 또는 XML .resx 파일에서 컴파일된 이진 파일입니다. 개체는 ResourceReader 독립 실행형 .resources 파일 또는 어셈블리에 포함된 .resources 파일을 나타낼 수 있습니다.

독립 실행형 .resources 파일에서 읽는 개체를 인스턴스화 ResourceReader 하려면 입력 스트림 또는 .resources 파일 이름이 포함된 문자열과 함께 클래스 생성자를 사용합니다 ResourceReader . 다음 예제에서는 두 가지 방법을 모두 보여 줍니다. 첫 번째는 파일 이름을 사용하여 명명 Resources1.resources 된 .resources 파일을 나타내는 개체를 인스턴스화 ResourceReader 합니다. 두 번째는 파일에서 만든 스트림을 사용하여 명명된 Resources2.resources .resources 파일을 나타내는 개체를 인스턴스화 ResourceReader 합니다.

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

포함된 .resources 파일을 나타내는 개체를 만들 ResourceReader 려면 .resources 파일이 포함된 어셈블리에서 개체를 인스턴스화 Assembly 합니다. 해당 메서드는 Assembly.GetManifestResourceStreamStream 생성자에 전달할 수 있는 개체를 ResourceReader(Stream) 반환합니다. 다음은 포함된 .resources 파일을 나타내는 개체를 인스턴스화하는 ResourceReader 예제입니다.

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 개체의 리소스 열거

.resources 파일에서 리소스를 열거하려면 개체를 반환하는 메서드를 System.Collections.IDictionaryEnumerator 호출 GetEnumerator 합니다. 메서드를 IDictionaryEnumerator.MoveNext 호출하여 한 리소스에서 다음 리소스로 이동합니다. .resources 파일의 모든 리소스가 열거되면 메서드가 반환 false 됩니다.

참고 항목

클래스는 ResourceReader 인터페이스와 메서드를 IEnumerableIEnumerable.GetEnumerator 구현하지만 메서드는 ResourceReader.GetEnumerator 구현을 IEnumerable.GetEnumerator 제공하지 않습니다. 대신 메서드는 ResourceReader.GetEnumerator 각 리소스의 이름/값 쌍에 대한 액세스를 제공하는 인터페이스 개체를 반환 IDictionaryEnumerator 합니다.

다음 두 가지 방법으로 컬렉션의 개별 리소스를 검색할 수 있습니다.

  • 컬렉션의 각 리소스를 System.Collections.IDictionaryEnumerator 반복하고 속성을 사용하여 System.Collections.IDictionaryEnumerator 리소스 이름과 값을 검색할 수 있습니다. 모든 리소스가 동일한 형식이거나 각 리소스의 데이터 형식을 알고 있는 경우 이 기술을 사용하는 것이 좋습니다.

  • 컬렉션을 반복 System.Collections.IDictionaryEnumerator 할 때 각 리소스의 이름을 검색하고 메서드를 GetResourceData 호출하여 리소스의 데이터를 검색할 수 있습니다. 각 리소스의 데이터 형식을 모르거나 이전 접근 방식에서 예외를 throw하는 경우 이 방법을 사용하는 것이 좋습니다.

IDictionaryEnumerator 속성을 사용하여 리소스 검색

.resources 파일에서 리소스를 열거하는 첫 번째 방법은 각 리소스의 이름/값 쌍을 직접 검색하는 것입니다. 메서드를 IDictionaryEnumerator.MoveNext 호출하여 컬렉션의 각 리소스로 이동한 후 속성에서 IDictionaryEnumerator.Key 리소스 이름과 속성의 리소스 데이터를 검색할 IDictionaryEnumerator.Value 수 있습니다.

다음 예제에서는 및 속성을 사용하여 .resources 파일에서 각 리소스의 이름과 값을 검색하는 IDictionaryEnumerator.KeyIDictionaryEnumerator.Value 방법을 보여 줍니다. 예제를 실행하려면 문자열 리소스를 정의하는 ApplicationResources.txt이라는 다음 텍스트 파일을 만듭니다.

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

그런 다음, 다음 명령을 사용하여 텍스트 리소스 파일을 ApplicationResources.resources라는 이진 파일로 변환할 수 있습니다.

resgen ApplicationResources.txt

다음 예제에서는 클래스를 ResourceReader 사용하여 독립 실행형 이진 .resources 파일의 각 리소스를 열거하고 해당 키 이름과 해당 값을 표시합니다.

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)

속성에서 IDictionaryEnumerator.Value 리소스 데이터를 검색하려고 하면 다음과 같은 예외가 throw됩니다.

  • 데이터가 예상 형식이 아닌 경우 A FormatException 입니다.
  • 데이터가 FileNotFoundException 속한 형식을 포함하는 어셈블리를 찾을 수 없는 경우입니다.
  • 데이터가 속한 형식을 찾을 수 없는 경우입니다 TypeLoadException .

.Resources 파일을 수정 된 경우 수동으로 형식이 정의 되어 있는 어셈블리는 애플리케이션과 함께 포함 되어 있지 않습니다 또는 실수로 삭제 된 경우 또는 이전에 실행 되는 이전 버전 어셈블리가 있는 경우 이러한 예외가 throw 되는 일반적으로 형식입니다. 이러한 예외 중 하나가 throw되면 다음 섹션과 같이 각 리소스를 열거하고 메서드를 GetResourceData 호출하여 리소스를 검색할 수 있습니다. 이 방법은 속성이 반환하려고 시도한 데이터 형식 IDictionaryEnumerator.Value 에 대한 몇 가지 정보를 제공합니다.

GetResourceData를 사용하여 이름으로 리소스 검색

.resources 파일에서 리소스를 열거하는 두 번째 방법은 메서드를 호출 IDictionaryEnumerator.MoveNext 하여 파일의 리소스를 탐색하는 작업도 포함합니다. 각 리소스에 대해 속성에서 IDictionaryEnumerator.Key 리소스의 이름을 검색한 다음, 메서드에 GetResourceData(String, String, Byte[]) 전달되어 리소스의 데이터를 검색합니다. 인수에서 resourceData 바이트 배열로 반환됩니다.

이 방법은 리소스 값을 형성하는 실제 바이트를 반환하기 때문에 리소스 이름 및 IDictionaryEnumerator.Value 속성에서 IDictionaryEnumerator.Key 값을 검색하는 것보다 더 어색합니다. 그러나 리소스를 검색하려고 하면 예외 GetResourceData 가 throw되는 경우 이 메서드는 리소스의 데이터 형식에 대한 정보를 제공하여 예외의 원본을 식별하는 데 도움이 될 수 있습니다. 리소스의 데이터 형식을 나타내는 문자열에 대한 자세한 내용은 다음을 참조하세요 GetResourceData.

다음 예제에서는 이 방법을 사용하여 리소스를 검색하고 throw되는 예외를 처리하는 방법을 보여 줍니다. 프로그래밍 방식으로 4개의 문자열, 1개의 부울, 1개의 정수 및 1개의 비트맵이 포함된 이진 .resources 파일을 만듭니다. 예제를 실행하려면 다음을 수행합니다.

  1. ContactResources.resources라는 .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();
            }
        }
    }
    

    소스 코드 파일의 이름은 CreateResources.cs. 다음 명령을 사용하여 C#에서 컴파일할 수 있습니다.

    csc CreateResources.cs /r:library.dll
    
  2. 다음 코드를 컴파일하고 실행하여 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();
        }
    }
    

    소스 코드를 수정한 후(예: 의도적으로 블록 끝에 try throwFormatException) 예제를 실행하여 일부 리소스 정보를 검색하거나 다시 만들 수 있는 호출 GetResourceData 방법을 확인할 수 있습니다.